nodebb-plugin-niki-loyalty 1.5.0 → 1.5.5
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 +69 -98
- package/niki-admin.txt +120 -143
- package/niki-kasa.txt +52 -22
- package/niki-prize.txt +200 -0
- package/niki-wallet.txt +415 -0
- package/package.json +1 -1
- package/static/lib/client.js +33 -26
- package/yeedek +313 -0
package/niki-prize.txt
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
<div class="niki-premium-widget">
|
|
2
|
+
<div class="widget-header">
|
|
3
|
+
<div class="header-top">
|
|
4
|
+
<div class="title-group">
|
|
5
|
+
<i class="fa fa-diamond gold-icon"></i>
|
|
6
|
+
<span class="widget-title">GÜNLÜK HEDEF</span>
|
|
7
|
+
</div>
|
|
8
|
+
<span class="points-badge" id="widget-user-points">...</span>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="progress-container">
|
|
12
|
+
<div class="progress-bar-bg">
|
|
13
|
+
<div class="progress-bar-fill" id="widget-daily-progress" style="width: 0%;"></div>
|
|
14
|
+
</div>
|
|
15
|
+
<div class="progress-text">
|
|
16
|
+
<span id="widget-daily-text" class="status-text">Yükleniyor...</span>
|
|
17
|
+
<span class="target">Hedef: ...</span>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="widget-list">
|
|
23
|
+
<div class="list-item" id="item-login">
|
|
24
|
+
<div class="icon-box purple-theme"><i class="fa fa-sign-in"></i></div>
|
|
25
|
+
<div class="item-details">
|
|
26
|
+
<span class="item-name">Günlük Giriş 👋</span>
|
|
27
|
+
<span class="item-sub" id="w-count-login">Giriş Yapılmadı</span>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="item-reward">...</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="list-item" id="item-new-topic">
|
|
33
|
+
<div class="icon-box blue-theme"><i class="fa fa-pencil"></i></div>
|
|
34
|
+
<div class="item-details">
|
|
35
|
+
<span class="item-name">Yeni Konu 📝</span>
|
|
36
|
+
<span class="item-sub" id="w-count-new_topic">...</span>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="item-reward">...</div>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div class="list-item" id="item-reply">
|
|
42
|
+
<div class="icon-box green-theme"><i class="fa fa-commenting"></i></div>
|
|
43
|
+
<div class="item-details">
|
|
44
|
+
<span class="item-name">Yorum Yazma 💬</span>
|
|
45
|
+
<span class="item-sub" id="w-count-reply">...</span>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="item-reward">...</div>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div class="list-item" id="item-read">
|
|
51
|
+
<div class="icon-box orange-theme"><i class="fa fa-book"></i></div>
|
|
52
|
+
<div class="item-details">
|
|
53
|
+
<span class="item-name">Konu Okuma 👀</span>
|
|
54
|
+
<span class="item-sub" id="w-count-read">...</span>
|
|
55
|
+
</div>
|
|
56
|
+
<div class="item-reward">...</div>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div class="list-item" id="item-like">
|
|
60
|
+
<div class="icon-box pink-theme"><i class="fa fa-heart"></i></div>
|
|
61
|
+
<div class="item-details">
|
|
62
|
+
<span class="item-name">Beğeni Etkileşimi ❤️🌟</span>
|
|
63
|
+
<span class="item-sub" id="w-count-like">...</span>
|
|
64
|
+
</div>
|
|
65
|
+
<div class="item-reward">...</div>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
<a href="/niki-wallet" class="widget-footer-btn">
|
|
70
|
+
Cüzdanı Görüntüle <i class="fa fa-chevron-right"></i>
|
|
71
|
+
</a>
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
<style>
|
|
76
|
+
/* =========================================
|
|
77
|
+
TEMAYA DUYARLI PREMIUM CSS
|
|
78
|
+
========================================= */
|
|
79
|
+
|
|
80
|
+
/* 1. Varsayılan (LIGHT MODE) Değişkenleri */
|
|
81
|
+
.niki-premium-widget {
|
|
82
|
+
--w-bg: #ffffff;
|
|
83
|
+
--w-border: #e9ecef;
|
|
84
|
+
--w-text-main: #333333;
|
|
85
|
+
--w-text-sub: #888888;
|
|
86
|
+
--w-hover: #f8f9fa;
|
|
87
|
+
--w-header-bg: #f8f9fa;
|
|
88
|
+
--w-progress-bg: #e0e0e0;
|
|
89
|
+
--w-footer-bg: #ffffff;
|
|
90
|
+
--w-footer-text: #666666;
|
|
91
|
+
--w-shadow: 0 4px 12px rgba(0,0,0,0.05);
|
|
92
|
+
|
|
93
|
+
background: var(--w-bg);
|
|
94
|
+
border: 1px solid var(--w-border);
|
|
95
|
+
border-radius: 12px;
|
|
96
|
+
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
97
|
+
color: var(--w-text-main);
|
|
98
|
+
overflow: hidden;
|
|
99
|
+
box-shadow: var(--w-shadow);
|
|
100
|
+
margin-bottom: 20px;
|
|
101
|
+
transition: all 0.3s ease;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* 2. DARK MODE (Otomatik Algılama) */
|
|
105
|
+
/* NodeBB genellikle body'ye 'skin-dark' veya 'dark' classı ekler. Ayrıca medya sorgusu ekledik. */
|
|
106
|
+
@media (prefers-color-scheme: dark), body.skin-dark, body.dark-mode, html.dark {
|
|
107
|
+
.niki-premium-widget {
|
|
108
|
+
--w-bg: #1e1e1e; /* Tema ile uyumlu koyu gri */
|
|
109
|
+
--w-border: #333333; /* İnce koyu çizgi */
|
|
110
|
+
--w-text-main: #e0e0e0; /* Açık gri metin */
|
|
111
|
+
--w-text-sub: #999999; /* Alt metin */
|
|
112
|
+
--w-hover: #252525; /* Hover rengi */
|
|
113
|
+
--w-header-bg: #222222; /* Header koyu */
|
|
114
|
+
--w-progress-bg: #333333;
|
|
115
|
+
--w-footer-bg: #1e1e1e;
|
|
116
|
+
--w-footer-text: #aaaaaa;
|
|
117
|
+
--w-shadow: 0 4px 20px rgba(0,0,0,0.3);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/* --- HEADER --- */
|
|
122
|
+
.widget-header {
|
|
123
|
+
background: var(--w-header-bg);
|
|
124
|
+
padding: 16px;
|
|
125
|
+
border-bottom: 1px solid var(--w-border);
|
|
126
|
+
}
|
|
127
|
+
.header-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
|
|
128
|
+
.title-group { display: flex; align-items: center; gap: 8px; }
|
|
129
|
+
.gold-icon { color: #ffd700; font-size: 14px; }
|
|
130
|
+
.widget-title { font-weight: 700; font-size: 12px; letter-spacing: 1px; text-transform: uppercase; color: var(--w-text-sub); }
|
|
131
|
+
.points-badge {
|
|
132
|
+
background: rgba(255, 215, 0, 0.15); color: #ffd700;
|
|
133
|
+
padding: 3px 8px; border-radius: 6px; font-size: 13px; font-weight: 800;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* --- PROGRESS BAR --- */
|
|
137
|
+
.progress-bar-bg {
|
|
138
|
+
height: 6px; background: var(--w-progress-bg);
|
|
139
|
+
border-radius: 3px; overflow: hidden; margin-bottom: 6px;
|
|
140
|
+
}
|
|
141
|
+
.progress-bar-fill {
|
|
142
|
+
height: 100%; background: linear-gradient(90deg, #ffd700, #ffaa00);
|
|
143
|
+
border-radius: 3px; transition: width 0.6s ease;
|
|
144
|
+
}
|
|
145
|
+
.progress-text { display: flex; justify-content: space-between; font-size: 11px; color: var(--w-text-sub); }
|
|
146
|
+
|
|
147
|
+
/* --- LİSTE ÖGELERİ --- */
|
|
148
|
+
.widget-list { padding: 4px 0; }
|
|
149
|
+
.list-item {
|
|
150
|
+
display: flex; align-items: center; padding: 12px 16px;
|
|
151
|
+
border-bottom: 1px solid var(--w-border);
|
|
152
|
+
transition: background 0.2s;
|
|
153
|
+
}
|
|
154
|
+
.list-item:last-child { border-bottom: none; }
|
|
155
|
+
.list-item:hover { background: var(--w-hover); }
|
|
156
|
+
|
|
157
|
+
/* İkon Kutuları (Şeffaf & Temiz) */
|
|
158
|
+
.icon-box {
|
|
159
|
+
width: 34px; height: 34px; border-radius: 10px;
|
|
160
|
+
display: flex; align-items: center; justify-content: center;
|
|
161
|
+
margin-right: 14px; font-size: 14px; flex-shrink: 0;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* İkon Renk Temaları */
|
|
165
|
+
.blue-theme { background: rgba(33, 150, 243, 0.1); color: #2196f3; }
|
|
166
|
+
.green-theme { background: rgba(76, 175, 80, 0.1); color: #4caf50; }
|
|
167
|
+
.orange-theme { background: rgba(255, 152, 0, 0.1); color: #ff9800; }
|
|
168
|
+
.pink-theme { background: rgba(233, 30, 99, 0.1); color: #e91e63; }
|
|
169
|
+
.purple-theme { background: rgba(156, 39, 176, 0.1); color: #9c27b0; }
|
|
170
|
+
|
|
171
|
+
/* Detaylar */
|
|
172
|
+
.item-details { flex-grow: 1; display: flex; flex-direction: column; }
|
|
173
|
+
.item-name { font-size: 13px; font-weight: 600; color: var(--w-text-main); margin-bottom: 2px; }
|
|
174
|
+
.item-sub { font-size: 11px; color: var(--w-text-sub); transition: color 0.3s; }
|
|
175
|
+
|
|
176
|
+
/* Ödül Puanı */
|
|
177
|
+
.item-reward {
|
|
178
|
+
font-weight: 700; font-size: 12px; color: #ffd700;
|
|
179
|
+
background: rgba(255, 215, 0, 0.08); padding: 4px 8px;
|
|
180
|
+
border-radius: 6px; white-space: nowrap;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* Footer Buton */
|
|
184
|
+
.widget-footer-btn {
|
|
185
|
+
display: flex; justify-content: center; align-items: center;
|
|
186
|
+
padding: 14px; background: var(--w-footer-bg);
|
|
187
|
+
color: var(--w-footer-text); text-decoration: none;
|
|
188
|
+
font-size: 12px; font-weight: 600;
|
|
189
|
+
border-top: 1px solid var(--w-border);
|
|
190
|
+
text-transform: uppercase; letter-spacing: 0.5px;
|
|
191
|
+
transition: all 0.2s;
|
|
192
|
+
}
|
|
193
|
+
.widget-footer-btn:hover { background: var(--w-hover); color: var(--w-text-main); }
|
|
194
|
+
|
|
195
|
+
/* --- TAMAMLANMIŞ GÖREV STİLİ --- */
|
|
196
|
+
.list-item.completed { opacity: 0.6; }
|
|
197
|
+
.list-item.completed .item-name { text-decoration: line-through; color: var(--w-text-sub); }
|
|
198
|
+
.list-item.completed .item-sub { color: #4caf50; font-weight: bold; }
|
|
199
|
+
.list-item.completed .icon-box { filter: grayscale(1); opacity: 0.5; }
|
|
200
|
+
</style>
|
package/niki-wallet.txt
CHANGED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
<style>
|
|
2
|
+
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;500;700;800&display=swap');
|
|
3
|
+
|
|
4
|
+
.niki-wallet-wrapper{
|
|
5
|
+
max-width:380px;margin:40px auto;background:#FFF;
|
|
6
|
+
border-radius:30px;box-shadow:0 20px 60px rgba(0,0,0,0.08);
|
|
7
|
+
overflow:hidden;text-align:center;position:relative;
|
|
8
|
+
font-family:'Poppins',sans-serif;border:1px solid #F0F0F0;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.niki-header-bg{background:#1a1a1a;height:140px;width:100%;position:absolute;top:0;left:0;border-radius:0 0 40px 40px;}
|
|
12
|
+
.niki-content{position:relative;z-index:1;padding:30px;padding-top:70px;}
|
|
13
|
+
|
|
14
|
+
.niki-avatar{width:110px;height:110px;border-radius:50%;background:#fff;margin:0 auto 15px;border:5px solid #fff;box-shadow:0 10px 30px rgba(0,0,0,0.1);display:flex;align-items:center;justify-content:center;position:relative;}
|
|
15
|
+
.niki-avatar img{width:100%;height:100%;object-fit:cover;border-radius:50%;}
|
|
16
|
+
|
|
17
|
+
.niki-balance-big{font-size:60px;font-weight:800;color:#1a1a1a;line-height:1;margin-bottom:5px;letter-spacing:-2px;}
|
|
18
|
+
.niki-label{color:#999;font-size:11px;font-weight:700;letter-spacing:2px;text-transform:uppercase;margin-bottom:25px;}
|
|
19
|
+
|
|
20
|
+
.niki-bar-box{background:#FAFAFA;border-radius:20px;padding:25px 20px 40px;margin:25px 0;border:1px solid #EEE;position:relative;}
|
|
21
|
+
.niki-track{background:#E0E0E0;height:12px;border-radius:10px;width:100%;margin:15px 0;position:relative;}
|
|
22
|
+
.niki-fill{height:100%;background:#C5A065;width:0%;transition:width 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);border-radius:10px;box-shadow:0 0 10px rgba(197,160,101,0.4);}
|
|
23
|
+
|
|
24
|
+
.tier-dot{position:absolute;top:50%;transform:translate(-50%,-50%);width:12px;height:12px;background:#fff;border:3px solid #ccc;border-radius:50%;z-index:2;transition:all 0.3s;}
|
|
25
|
+
.tier-dot.reached{border-color:#C5A065;background:#C5A065;}
|
|
26
|
+
|
|
27
|
+
.tier-label{position:absolute;top:18px;transform:translateX(-50%);font-size:9px;color:#aaa;font-weight:600;width:60px;text-align:center;line-height:1.1;}
|
|
28
|
+
.tier-dot.reached + .tier-label{color:#C5A065;}
|
|
29
|
+
|
|
30
|
+
/* Ödül seçim listesi */
|
|
31
|
+
.niki-reward-list{margin:20px 0 10px;text-align:left;}
|
|
32
|
+
.niki-reward-item{
|
|
33
|
+
display:flex;align-items:center;padding:14px 16px;
|
|
34
|
+
border:2px solid #EEE;border-radius:14px;margin-bottom:10px;
|
|
35
|
+
cursor:pointer;transition:all 0.2s;background:#fff;
|
|
36
|
+
}
|
|
37
|
+
.niki-reward-item:hover{border-color:#ddd;background:#FAFAFA;}
|
|
38
|
+
.niki-reward-item.selected{border-color:#C5A065;background:#FFF9F0;}
|
|
39
|
+
.niki-reward-item.locked{opacity:0.4;cursor:not-allowed;pointer-events:none;}
|
|
40
|
+
|
|
41
|
+
.niki-reward-radio{
|
|
42
|
+
width:20px;height:20px;border-radius:50%;border:2px solid #ccc;
|
|
43
|
+
margin-right:12px;display:flex;align-items:center;justify-content:center;flex-shrink:0;
|
|
44
|
+
transition:all 0.2s;
|
|
45
|
+
}
|
|
46
|
+
.niki-reward-item.selected .niki-reward-radio{border-color:#C5A065;background:#C5A065;}
|
|
47
|
+
.niki-reward-item.selected .niki-reward-radio::after{content:'';width:8px;height:8px;border-radius:50%;background:#fff;}
|
|
48
|
+
|
|
49
|
+
.niki-reward-info{flex:1;}
|
|
50
|
+
.niki-reward-name{font-size:13px;font-weight:700;color:#1a1a1a;}
|
|
51
|
+
.niki-reward-cost{font-size:11px;color:#999;margin-top:2px;}
|
|
52
|
+
|
|
53
|
+
.niki-reward-badge{
|
|
54
|
+
font-size:11px;font-weight:700;padding:4px 10px;border-radius:8px;
|
|
55
|
+
background:#F0F0F0;color:#999;
|
|
56
|
+
}
|
|
57
|
+
.niki-reward-item.selected .niki-reward-badge{background:#C5A065;color:#fff;}
|
|
58
|
+
|
|
59
|
+
.niki-btn{
|
|
60
|
+
background:#1a1a1a;color:#fff;width:100%;padding:20px;
|
|
61
|
+
border-radius:18px;font-size:14px;font-weight:700;border:none;
|
|
62
|
+
cursor:pointer;display:flex;align-items:center;justify-content:center;gap:8px;
|
|
63
|
+
transition:transform 0.2s, box-shadow 0.2s;
|
|
64
|
+
}
|
|
65
|
+
.niki-btn:active{transform:scale(0.95);}
|
|
66
|
+
.niki-btn:disabled{background:#E0E0E0;color:#AAA;cursor:not-allowed;}
|
|
67
|
+
|
|
68
|
+
.qr-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(10,10,10,0.95);z-index:10000;display:none;align-items:center;justify-content:center;backdrop-filter:blur(10px);}
|
|
69
|
+
.ticket-card{background:#fff;width:320px;border-radius:30px;overflow:hidden;text-align:center;position:relative;animation:cardPop 0.4s cubic-bezier(0.175,0.885,0.32,1.275);box-shadow:0 0 0 8px rgba(255,255,255,0.1),0 30px 80px rgba(0,0,0,0.8);}
|
|
70
|
+
@keyframes cardPop{from{transform:scale(0.8) translateY(50px);opacity:0;}to{transform:scale(1) translateY(0);opacity:1;}}
|
|
71
|
+
|
|
72
|
+
.ticket-top{background:#1a1a1a;padding:25px;color:#C5A065;font-weight:700;letter-spacing:2px;font-size:14px;}
|
|
73
|
+
.ticket-body{padding:40px 30px;position:relative;}
|
|
74
|
+
#qrcode{display:flex;justify-content:center;margin-bottom:30px;}
|
|
75
|
+
#qrcode img{border:10px solid #fff;border-radius:10px;box-shadow:0 10px 30px rgba(0,0,0,0.1);}
|
|
76
|
+
.timer-wrapper{width:100%;height:6px;background:#eee;border-radius:10px;overflow:hidden;margin-top:10px;}
|
|
77
|
+
.timer-bar{height:100%;background:#C5A065;width:100%;transition:width 1s linear;}
|
|
78
|
+
.timer-text{font-size:12px;color:#888;margin-top:8px;font-weight:600;}
|
|
79
|
+
.close-circle{position:absolute;top:15px;right:15px;width:30px;height:30px;background:rgba(255,255,255,0.2);border-radius:50%;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;transition:background 0.2s;}
|
|
80
|
+
.close-circle:hover{background:rgba(255,255,255,0.4);}
|
|
81
|
+
|
|
82
|
+
.success-view{display:none;padding:40px 20px;}
|
|
83
|
+
.success-icon{width:100px;height:100px;background:#2E7D32;color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:50px;margin:0 auto 20px;box-shadow:0 10px 30px rgba(46,125,50,0.3);animation:popCheck 0.5s ease;}
|
|
84
|
+
@keyframes popCheck{0%{transform:scale(0);}80%{transform:scale(1.1);}100%{transform:scale(1);}}
|
|
85
|
+
</style>
|
|
86
|
+
|
|
87
|
+
<div class="niki-wallet-wrapper" id="niki-wallet-root">
|
|
88
|
+
<div class="niki-header-bg"></div>
|
|
89
|
+
|
|
90
|
+
<div class="niki-content">
|
|
91
|
+
<div class="niki-avatar"><img src="" id="niki-logo-main"></div>
|
|
92
|
+
<div class="niki-balance-big" id="my-points">...</div>
|
|
93
|
+
<div class="niki-label">MEVCUT PUAN</div>
|
|
94
|
+
|
|
95
|
+
<div class="niki-bar-box">
|
|
96
|
+
<div style="display:flex; justify-content:space-between; font-size:12px; font-weight:700; color:#1a1a1a;">
|
|
97
|
+
<span>HEDEFLER</span><span id="target-txt">...</span>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div class="niki-track">
|
|
101
|
+
<div class="niki-fill" id="prog-bar"></div>
|
|
102
|
+
<div id="tier-dots-container"></div>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<div style="font-size:10px; color:#aaa; margin-top:25px; text-align:center;">Ödüller Niki Kasasından alınır</div>
|
|
106
|
+
<div style="font-size:10px; color:#aaa; margin-top:25px; text-align:center;">Kurabiye Ödülü kahvenin yanında ücretsizdir</div>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<div id="reward-list" class="niki-reward-list"></div>
|
|
110
|
+
|
|
111
|
+
<button id="btn-qr" class="niki-btn" onclick="openQR()" disabled>
|
|
112
|
+
<i class="fa fa-lock"></i> PUAN YETERSİZ
|
|
113
|
+
</button>
|
|
114
|
+
|
|
115
|
+
<div style="margin-top:25px; font-size:10px; color:#ccc;">
|
|
116
|
+
NIKI THE CAT COFFEE © LOYALTY
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<div id="modal-qr" class="qr-overlay">
|
|
122
|
+
<div class="ticket-card">
|
|
123
|
+
<div class="close-circle" onclick="closeQR()"><i class="fa fa-times"></i></div>
|
|
124
|
+
|
|
125
|
+
<div id="view-code">
|
|
126
|
+
<div class="ticket-top" id="qr-reward-label">KASAYA GÖSTERİNİZ</div>
|
|
127
|
+
<div class="ticket-body">
|
|
128
|
+
<div id="qrcode"></div>
|
|
129
|
+
<div style="font-size:14px; font-weight:700; color:#1a1a1a; margin-top:10px;">TARANIYOR...</div>
|
|
130
|
+
<div class="timer-wrapper"><div class="timer-bar" id="time-bar"></div></div>
|
|
131
|
+
<div class="timer-text" id="timer-txt">2:00</div>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
<div id="view-success" class="success-view">
|
|
136
|
+
<div class="success-icon"><i class="fa fa-check"></i></div>
|
|
137
|
+
<h2 style="font-size:24px; color:#1a1a1a; margin-bottom:10px;">AFİYET OLSUN!</h2>
|
|
138
|
+
<p style="color:#888; font-size:14px; margin-bottom:20px;">Ödeme alındı, ödülün verildi.</p>
|
|
139
|
+
<button class="niki-btn" onclick="closeQR()" style="padding:15px; font-size:14px;">TAMAM</button>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
|
|
144
|
+
<script>
|
|
145
|
+
(function () {
|
|
146
|
+
function waitAndInit() {
|
|
147
|
+
console.log('[Niki-Wallet] waitAndInit, jQuery:', typeof $ !== 'undefined', 'pathname:', window.location.pathname);
|
|
148
|
+
if (typeof $ === 'undefined' || typeof jQuery === 'undefined') {
|
|
149
|
+
setTimeout(waitAndInit, 100);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (window.location.pathname.indexOf('niki-wallet') === -1) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
console.log('[Niki-Wallet] Başlatılıyor...');
|
|
156
|
+
initWallet();
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function initWallet() {
|
|
160
|
+
function loadScript(url, check, cb) {
|
|
161
|
+
if (check()) return cb();
|
|
162
|
+
var s = document.createElement('script');
|
|
163
|
+
s.src = url;
|
|
164
|
+
s.onload = cb;
|
|
165
|
+
s.onerror = function () { console.error('[Niki-Wallet] Script HATA:', url); cb(); };
|
|
166
|
+
document.head.appendChild(s);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function loadDeps(cb) {
|
|
170
|
+
loadScript('https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js',
|
|
171
|
+
function () { return typeof QRCode !== 'undefined'; },
|
|
172
|
+
function () {
|
|
173
|
+
loadScript('https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js',
|
|
174
|
+
function () { return typeof confetti !== 'undefined'; },
|
|
175
|
+
cb);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
var pollInterval = null;
|
|
180
|
+
var initialPoints = 0;
|
|
181
|
+
var selectedRewardIndex = -1; // Backend orijinal REWARDS dizisindeki index
|
|
182
|
+
var REWARDS_SORTED = []; // Küçükten büyüğe (UI için)
|
|
183
|
+
var REWARDS_ORIGINAL = []; // Backend'den geldiği gibi (index referansı)
|
|
184
|
+
|
|
185
|
+
// Kısa ödül adları (progress bar dot label için)
|
|
186
|
+
var SHORT_NAMES = {
|
|
187
|
+
'1 Kurabiye 🍪': 'Kurabiye',
|
|
188
|
+
'%30 İndirimli Kahve': '%30 İnd.',
|
|
189
|
+
'%60 İndirimli Kahve': '%60 İnd.',
|
|
190
|
+
'Ücretsiz Kahve ☕': 'Kahve'
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
function safeLoadData() {
|
|
194
|
+
if (!$('#niki-wallet-root').length) return;
|
|
195
|
+
|
|
196
|
+
var rp = (typeof config !== 'undefined' && config.relative_path) ? config.relative_path : '';
|
|
197
|
+
$('#niki-logo-main').attr('src', rp + '/plugins/nodebb-plugin-niki-loyalty/static/logo.png');
|
|
198
|
+
|
|
199
|
+
console.log('[Niki-Wallet] API çağrılıyor...');
|
|
200
|
+
$.get('/api/niki-loyalty/wallet-data')
|
|
201
|
+
.done(function (data) {
|
|
202
|
+
console.log('[Niki-Wallet] API OK, points:', data && data.points);
|
|
203
|
+
var p = parseInt(data && data.points, 10) || 0;
|
|
204
|
+
initialPoints = p;
|
|
205
|
+
$('#my-points').text(p);
|
|
206
|
+
|
|
207
|
+
// Rewards'ı backend'den al
|
|
208
|
+
REWARDS_ORIGINAL = data.rewards || [];
|
|
209
|
+
// Küçükten büyüğe sırala (UI için), her item'a orijinal index'i ekle
|
|
210
|
+
REWARDS_SORTED = REWARDS_ORIGINAL.map(function (r, i) {
|
|
211
|
+
return { cost: r.cost, name: r.name, origIndex: i };
|
|
212
|
+
}).sort(function (a, b) { return a.cost - b.cost; });
|
|
213
|
+
|
|
214
|
+
var maxGoal = REWARDS_SORTED.length ? REWARDS_SORTED[REWARDS_SORTED.length - 1].cost : 250;
|
|
215
|
+
$('#target-txt').text(maxGoal);
|
|
216
|
+
|
|
217
|
+
// Progress bar
|
|
218
|
+
var pct = (p / maxGoal) * 100;
|
|
219
|
+
if (pct > 100) pct = 100;
|
|
220
|
+
$('#prog-bar').css('width', '0%');
|
|
221
|
+
setTimeout(function () { $('#prog-bar').css('width', pct + '%'); }, 60);
|
|
222
|
+
|
|
223
|
+
// Dinamik tier dots
|
|
224
|
+
var dotsHtml = '';
|
|
225
|
+
for (var d = 0; d < REWARDS_SORTED.length; d++) {
|
|
226
|
+
var leftPct = (REWARDS_SORTED[d].cost / maxGoal) * 100;
|
|
227
|
+
var reached = p >= REWARDS_SORTED[d].cost ? ' reached' : '';
|
|
228
|
+
var shortName = SHORT_NAMES[REWARDS_SORTED[d].name] || REWARDS_SORTED[d].name;
|
|
229
|
+
dotsHtml += '<div class="tier-dot' + reached + '" style="left:' + leftPct + '%;"></div>';
|
|
230
|
+
dotsHtml += '<div class="tier-label" style="left:' + leftPct + '%;' + (reached ? 'color:#C5A065;' : '') + '">' + shortName + '</div>';
|
|
231
|
+
}
|
|
232
|
+
$('#tier-dots-container').html(dotsHtml);
|
|
233
|
+
|
|
234
|
+
// Ödül seçim listesi
|
|
235
|
+
buildRewardList(p, data.canRedeem, data.walletGroups);
|
|
236
|
+
})
|
|
237
|
+
.fail(function (xhr) {
|
|
238
|
+
console.error('[Niki-Wallet] API HATA! Status:', xhr.status);
|
|
239
|
+
setTimeout(function () {
|
|
240
|
+
if ($('#niki-wallet-root').length) safeLoadData();
|
|
241
|
+
}, 500);
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function buildRewardList(points, canRedeem, walletGroups) {
|
|
246
|
+
var $list = $('#reward-list');
|
|
247
|
+
$list.empty();
|
|
248
|
+
selectedRewardIndex = -1;
|
|
249
|
+
|
|
250
|
+
// Grup üyesi değilse uyarı göster, ödüller kilitli
|
|
251
|
+
if (!canRedeem) {
|
|
252
|
+
var premiumUrl = 'https://forum.ieu.app/pay/checkout?uid=' + (app.user && app.user.uid ? app.user.uid : '');
|
|
253
|
+
$list.html(
|
|
254
|
+
'<div style="background:#FFF3E0;border:1px solid #FFE0B2;border-radius:14px;padding:20px;text-align:center;margin-bottom:10px;">' +
|
|
255
|
+
'<div style="font-size:24px;margin-bottom:10px;"><i class="fa fa-lock"></i></div>' +
|
|
256
|
+
'<div style="font-size:13px;font-weight:700;color:#E65100;margin-bottom:6px;">Ödül Kullanımı Kilitli</div>' +
|
|
257
|
+
'<div style="font-size:11px;color:#BF360C;margin-bottom:14px;">Ödül kullanmak için Premium, Lite veya VIP üyesi olmalısın.</div>' +
|
|
258
|
+
'<a href="' + premiumUrl + '" style="display:inline-block;background:#C5A065;color:#fff;font-weight:700;font-size:13px;padding:12px 24px;border-radius:12px;text-decoration:none;transition:transform 0.2s;">Premium Olmak İçin Tıkla <i class="fa fa-arrow-right"></i></a>' +
|
|
259
|
+
'</div>'
|
|
260
|
+
);
|
|
261
|
+
$('#btn-qr').prop('disabled', true)
|
|
262
|
+
.css('background', '#E0E0E0')
|
|
263
|
+
.html('<i class="fa fa-lock"></i> GRUP ÜYELİĞİ GEREKLİ');
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Büyükten küçüğe göster
|
|
268
|
+
var displayList = REWARDS_SORTED.slice().reverse();
|
|
269
|
+
|
|
270
|
+
for (var i = 0; i < displayList.length; i++) {
|
|
271
|
+
var r = displayList[i];
|
|
272
|
+
var canAfford = points >= r.cost;
|
|
273
|
+
|
|
274
|
+
var $item = $('<div class="niki-reward-item' + (canAfford ? '' : ' locked') + '"></div>');
|
|
275
|
+
$item.attr('data-orig-index', r.origIndex);
|
|
276
|
+
$item.html(
|
|
277
|
+
'<div class="niki-reward-radio"></div>' +
|
|
278
|
+
'<div class="niki-reward-info">' +
|
|
279
|
+
'<div class="niki-reward-name">' + r.name + '</div>' +
|
|
280
|
+
'<div class="niki-reward-cost">' + r.cost + ' Puan</div>' +
|
|
281
|
+
'</div>' +
|
|
282
|
+
'<div class="niki-reward-badge">' + (canAfford ? 'Kullanılabilir' : points + '/' + r.cost) + '</div>'
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
if (canAfford) {
|
|
286
|
+
$item.on('click', function () {
|
|
287
|
+
var origIdx = parseInt($(this).attr('data-orig-index'), 10);
|
|
288
|
+
$('.niki-reward-item').removeClass('selected');
|
|
289
|
+
$(this).addClass('selected');
|
|
290
|
+
selectedRewardIndex = origIdx;
|
|
291
|
+
var reward = REWARDS_ORIGINAL[origIdx];
|
|
292
|
+
$('#btn-qr').prop('disabled', false)
|
|
293
|
+
.css('background', '#1a1a1a')
|
|
294
|
+
.html('<i class="fa fa-qrcode"></i> KULLAN: ' + reward.name.toUpperCase());
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
$list.append($item);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Hiçbir ödül alınamıyorsa
|
|
302
|
+
var minCost = REWARDS_SORTED.length ? REWARDS_SORTED[0].cost : 60;
|
|
303
|
+
if (points < minCost) {
|
|
304
|
+
$('#btn-qr').prop('disabled', true)
|
|
305
|
+
.css('background', '#E0E0E0')
|
|
306
|
+
.html('<i class="fa fa-lock"></i> ' + Math.max(0, minCost - points) + ' PUAN EKSİK');
|
|
307
|
+
} else {
|
|
308
|
+
$('#btn-qr').prop('disabled', true)
|
|
309
|
+
.css('background', '#E0E0E0')
|
|
310
|
+
.html('<i class="fa fa-hand-pointer-o"></i> ÖDÜL SEÇİNİZ');
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
window.openQR = function () {
|
|
315
|
+
if (selectedRewardIndex < 0) {
|
|
316
|
+
if (typeof app !== 'undefined' && app.alertError) app.alertError('Lütfen bir ödül seçin.');
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
var reward = REWARDS_ORIGINAL[selectedRewardIndex];
|
|
320
|
+
if (!confirm(reward.name + ' (' + reward.cost + ' Puan) kullanmak istediğine emin misin?')) return;
|
|
321
|
+
|
|
322
|
+
loadDeps(function () {
|
|
323
|
+
$.post('/api/niki-loyalty/generate-qr', {
|
|
324
|
+
_csrf: config.csrf_token,
|
|
325
|
+
rewardIndex: selectedRewardIndex
|
|
326
|
+
}, function (res) {
|
|
327
|
+
if (res && res.success) {
|
|
328
|
+
$('#modal-qr').fadeIn(200).css('display', 'flex');
|
|
329
|
+
$('#view-code').show(); $('#view-success').hide();
|
|
330
|
+
$('#qrcode').empty();
|
|
331
|
+
$('#qr-reward-label').text(res.rewardName || 'KASAYA GÖSTERİNİZ');
|
|
332
|
+
|
|
333
|
+
new QRCode(document.getElementById("qrcode"), {
|
|
334
|
+
text: res.token,
|
|
335
|
+
width: 260, height: 260,
|
|
336
|
+
colorDark: "#000000", colorLight: "#ffffff",
|
|
337
|
+
correctLevel: QRCode.CorrectLevel.L
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
startTimer(120);
|
|
341
|
+
startPolling();
|
|
342
|
+
} else {
|
|
343
|
+
if (typeof app !== 'undefined' && app.alertError) app.alertError(res && res.message ? res.message : 'Hata');
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
function startPolling() {
|
|
350
|
+
clearInterval(pollInterval);
|
|
351
|
+
pollInterval = setInterval(function () {
|
|
352
|
+
if (!$('#modal-qr').is(':visible')) { clearInterval(pollInterval); return; }
|
|
353
|
+
|
|
354
|
+
$.get('/api/niki-loyalty/wallet-data', function (data) {
|
|
355
|
+
var currentP = parseInt(data && data.points, 10) || 0;
|
|
356
|
+
if (currentP < initialPoints) {
|
|
357
|
+
clearInterval(pollInterval);
|
|
358
|
+
showSuccess();
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}, 2000);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function showSuccess() {
|
|
365
|
+
$('#view-code').hide();
|
|
366
|
+
$('#view-success').fadeIn(300);
|
|
367
|
+
if (typeof confetti === 'function') {
|
|
368
|
+
confetti({ particleCount: 150, spread: 70, origin: { y: 0.6 }, colors: ['#C5A065', '#1a1a1a', '#ffffff'] });
|
|
369
|
+
}
|
|
370
|
+
try { new Audio('https://freesound.org/data/previews/171/171671_2437358-lq.mp3').play(); } catch (e) {}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function startTimer(duration) {
|
|
374
|
+
var timer = duration;
|
|
375
|
+
$('#time-bar').css('width', '100%');
|
|
376
|
+
|
|
377
|
+
var countdown = setInterval(function () {
|
|
378
|
+
if (!$('#modal-qr').is(':visible') || $('#view-success').is(':visible')) {
|
|
379
|
+
clearInterval(countdown); return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
var minutes = Math.floor(timer / 60);
|
|
383
|
+
var seconds = timer % 60;
|
|
384
|
+
$('#timer-txt').text(minutes + ":" + (seconds < 10 ? "0" + seconds : seconds));
|
|
385
|
+
|
|
386
|
+
var pct = (timer / duration) * 100;
|
|
387
|
+
$('#time-bar').css('width', pct + '%');
|
|
388
|
+
|
|
389
|
+
timer--;
|
|
390
|
+
if (timer < 0) {
|
|
391
|
+
clearInterval(countdown);
|
|
392
|
+
closeQR();
|
|
393
|
+
if (typeof app !== 'undefined' && app.alertError) app.alertError("Süre doldu.");
|
|
394
|
+
}
|
|
395
|
+
}, 1000);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
window.closeQR = function () {
|
|
399
|
+
$('#modal-qr').fadeOut(200);
|
|
400
|
+
clearInterval(pollInterval);
|
|
401
|
+
pollInterval = null;
|
|
402
|
+
setTimeout(safeLoadData, 200);
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
// Hemen yükle
|
|
406
|
+
safeLoadData();
|
|
407
|
+
|
|
408
|
+
// Arka planda QR kütüphanelerini yükle
|
|
409
|
+
loadDeps(function () { console.log('[Niki-Wallet] QR kütüphaneleri hazır.'); });
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Başlat
|
|
413
|
+
waitAndInit();
|
|
414
|
+
})();
|
|
415
|
+
</script>
|