vantuz 3.5.18 → 4.0.3
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/cli.js +9 -9
- package/config.js +6 -6
- package/core/agent-loop.js +6 -6
- package/core/agent.js +6 -6
- package/core/ai-copilot.js +461 -0
- package/core/ai-provider.js +60 -10
- package/core/automation.js +8 -8
- package/core/cache-manager.js +232 -0
- package/core/channels.js +8 -8
- package/core/dashboard.js +5 -5
- package/core/database-manager.js +331 -0
- package/core/database.js +124 -83
- package/core/eia-brain.js +2 -2
- package/core/eia-monitor.js +7 -7
- package/core/engine.js +24 -24
- package/core/error-handler.js +203 -0
- package/core/gateway.js +9 -9
- package/core/learning.js +7 -7
- package/core/license-manager.js +1 -1
- package/core/license.js +6 -6
- package/core/logger.js +228 -0
- package/core/marketplace-adapter.js +5 -5
- package/core/memory.js +6 -6
- package/core/multi-agent.js +180 -0
- package/core/openclaw-bridge.js +6 -6
- package/core/queue.js +3 -3
- package/core/scheduler.js +6 -6
- package/core/scrapers/Scraper.js +1 -1
- package/core/scrapers/TrendyolScraper.js +1 -1
- package/core/self-healer.js +8 -6
- package/core/unified-product.js +8 -8
- package/core/vector-db.js +5 -5
- package/core/vision-service.js +5 -5
- package/desktop/index.html +2804 -0
- package/desktop/main.js +97 -0
- package/desktop/preload.js +30 -0
- package/dev.sh +5 -0
- package/index.js +484 -116
- package/modules/crm/sentiment-crm.js +4 -4
- package/modules/healer/listing-healer.js +2 -2
- package/modules/oracle/predictor.js +5 -5
- package/modules/researcher/agent.js +4 -4
- package/modules/war-room/competitor-tracker.js +5 -5
- package/modules/war-room/pricing-engine.js +5 -5
- package/nodes/warehouse.js +5 -5
- package/onboard.js +1 -1
- package/package.json +11 -3
- package/pkg.json +26 -0
- package/plugins/vantuz/index.js +16 -17
- package/plugins/vantuz/memory/hippocampus.js +3 -3
- package/plugins/vantuz/platforms/_request.js +1 -1
- package/plugins/vantuz/platforms/_template.js +2 -2
- package/plugins/vantuz/platforms/amazon.js +3 -3
- package/plugins/vantuz/platforms/ciceksepeti.js +2 -2
- package/plugins/vantuz/platforms/hepsiburada.js +2 -2
- package/plugins/vantuz/platforms/index.js +9 -24
- package/plugins/vantuz/platforms/n11.js +3 -3
- package/plugins/vantuz/platforms/pazarama.js +2 -2
- package/plugins/vantuz/platforms/pttavm.js +2 -2
- package/plugins/vantuz/platforms/trendyol.js +3 -3
- package/plugins/vantuz/services/alerts.js +1 -1
- package/plugins/vantuz/services/scheduler.js +1 -1
- package/plugins/vantuz/tools/nl-parser.js +1 -1
- package/plugins/vantuz/tools/quick-report.js +2 -2
- package/plugins/vantuz/tools/repricer.js +1 -1
- package/plugins/vantuz/tools/vision.js +3 -3
- package/server/app.js +8 -8
- package/DOCS_TR.md +0 -80
- package/modules/team/agents/base.js +0 -92
- package/modules/team/agents/dev.js +0 -33
- package/modules/team/agents/josh.js +0 -40
- package/modules/team/agents/marketing.js +0 -33
- package/modules/team/agents/milo.js +0 -36
- package/modules/team/index.js +0 -78
- package/modules/team/shared-memory.js +0 -87
- package/n11docs.md +0 -1680
- package/openclawdocs.md +0 -3
- package/vantuz.sqlite +0 -0
- package/workspace/AGENTS.md +0 -73
- package/workspace/BRAND.md +0 -29
- package/workspace/SOUL.md +0 -72
- package/workspace/team/DECISIONS.md +0 -3
- package/workspace/team/GOALS.md +0 -3
- package/workspace/team/PROJECT_STATUS.md +0 -3
- package/workspace/team/agents/dev/SOUL.md +0 -12
- package/workspace/team/agents/josh/SOUL.md +0 -12
- package/workspace/team/agents/marketing/SOUL.md +0 -12
- package/workspace/team/agents/milo/SOUL.md +0 -12
|
@@ -0,0 +1,2804 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="tr">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>VANTUZ - E-Ticaret Yönetim Platformu</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
:root {
|
|
15
|
+
--bg-primary: #0a0a0f;
|
|
16
|
+
--bg-secondary: #12121a;
|
|
17
|
+
--bg-tertiary: #1a1a24;
|
|
18
|
+
--border-color: #2a2a3a;
|
|
19
|
+
--accent: #6366f1;
|
|
20
|
+
--accent-hover: #818cf8;
|
|
21
|
+
--text-primary: #f4f4f5;
|
|
22
|
+
--text-secondary: #a1a1aa;
|
|
23
|
+
--success: #22c55e;
|
|
24
|
+
--warning: #f59e0b;
|
|
25
|
+
--error: #ef4444;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
body {
|
|
29
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
30
|
+
background: var(--bg-primary);
|
|
31
|
+
color: var(--text-primary);
|
|
32
|
+
height: 100vh;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Custom Title Bar */
|
|
37
|
+
.titlebar {
|
|
38
|
+
height: 40px;
|
|
39
|
+
background: var(--bg-secondary);
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
justify-content: space-between;
|
|
43
|
+
padding: 0 10px;
|
|
44
|
+
-webkit-app-region: drag;
|
|
45
|
+
border-bottom: 1px solid var(--border-color);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.titlebar-left {
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: 10px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.logo {
|
|
55
|
+
font-size: 18px;
|
|
56
|
+
font-weight: 700;
|
|
57
|
+
color: var(--accent);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.titlebar-right {
|
|
61
|
+
display: flex;
|
|
62
|
+
gap: 5px;
|
|
63
|
+
-webkit-app-region: no-drag;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.window-btn {
|
|
67
|
+
width: 32px;
|
|
68
|
+
height: 32px;
|
|
69
|
+
border: none;
|
|
70
|
+
background: transparent;
|
|
71
|
+
color: var(--text-secondary);
|
|
72
|
+
cursor: pointer;
|
|
73
|
+
border-radius: 6px;
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
font-size: 14px;
|
|
78
|
+
transition: all 0.2s;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.window-btn:hover {
|
|
82
|
+
background: var(--bg-tertiary);
|
|
83
|
+
color: var(--text-primary);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.window-btn.close:hover {
|
|
87
|
+
background: var(--error);
|
|
88
|
+
color: white;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Main Layout */
|
|
92
|
+
.app-container {
|
|
93
|
+
display: flex;
|
|
94
|
+
height: calc(100vh - 40px);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* Sidebar */
|
|
98
|
+
.sidebar {
|
|
99
|
+
width: 260px;
|
|
100
|
+
background: var(--bg-secondary);
|
|
101
|
+
border-right: 1px solid var(--border-color);
|
|
102
|
+
padding: 20px 0;
|
|
103
|
+
display: flex;
|
|
104
|
+
flex-direction: column;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.sidebar-header {
|
|
108
|
+
padding: 0 20px 20px;
|
|
109
|
+
border-bottom: 1px solid var(--border-color);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.user-info {
|
|
113
|
+
display: flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
gap: 12px;
|
|
116
|
+
margin-top: 15px;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.user-avatar {
|
|
120
|
+
width: 40px;
|
|
121
|
+
height: 40px;
|
|
122
|
+
border-radius: 50%;
|
|
123
|
+
background: var(--accent);
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
font-weight: 600;
|
|
128
|
+
font-size: 16px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.user-name {
|
|
132
|
+
font-weight: 600;
|
|
133
|
+
font-size: 14px;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.user-plan {
|
|
137
|
+
font-size: 12px;
|
|
138
|
+
color: var(--text-secondary);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.sidebar-nav {
|
|
142
|
+
flex: 1;
|
|
143
|
+
padding: 20px 10px;
|
|
144
|
+
overflow-y: auto;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.nav-section {
|
|
148
|
+
margin-bottom: 25px;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.nav-section-title {
|
|
152
|
+
font-size: 11px;
|
|
153
|
+
text-transform: uppercase;
|
|
154
|
+
color: var(--text-secondary);
|
|
155
|
+
padding: 0 10px;
|
|
156
|
+
margin-bottom: 8px;
|
|
157
|
+
letter-spacing: 0.5px;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.nav-item {
|
|
161
|
+
display: flex;
|
|
162
|
+
align-items: center;
|
|
163
|
+
gap: 12px;
|
|
164
|
+
padding: 12px 15px;
|
|
165
|
+
border-radius: 8px;
|
|
166
|
+
cursor: pointer;
|
|
167
|
+
transition: all 0.2s;
|
|
168
|
+
color: var(--text-secondary);
|
|
169
|
+
margin: 2px 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.nav-item:hover {
|
|
173
|
+
background: var(--bg-tertiary);
|
|
174
|
+
color: var(--text-primary);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.nav-item.active {
|
|
178
|
+
background: var(--accent);
|
|
179
|
+
color: white;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.nav-icon {
|
|
183
|
+
font-size: 18px;
|
|
184
|
+
width: 24px;
|
|
185
|
+
text-align: center;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.nav-badge {
|
|
189
|
+
margin-left: auto;
|
|
190
|
+
background: var(--error);
|
|
191
|
+
color: white;
|
|
192
|
+
font-size: 11px;
|
|
193
|
+
padding: 2px 6px;
|
|
194
|
+
border-radius: 10px;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* Main Content */
|
|
198
|
+
.main-content {
|
|
199
|
+
flex: 1;
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-direction: column;
|
|
202
|
+
overflow: hidden;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.page {
|
|
206
|
+
display: none;
|
|
207
|
+
padding: 25px;
|
|
208
|
+
overflow-y: auto;
|
|
209
|
+
flex: 1;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.page.active {
|
|
213
|
+
display: block;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* Dashboard Grid */
|
|
217
|
+
.dashboard-header {
|
|
218
|
+
display: flex;
|
|
219
|
+
justify-content: space-between;
|
|
220
|
+
align-items: center;
|
|
221
|
+
margin-bottom: 25px;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.dashboard-title {
|
|
225
|
+
font-size: 24px;
|
|
226
|
+
font-weight: 600;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.dashboard-subtitle {
|
|
230
|
+
color: var(--text-secondary);
|
|
231
|
+
font-size: 14px;
|
|
232
|
+
margin-top: 5px;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.stats-grid {
|
|
236
|
+
display: grid;
|
|
237
|
+
grid-template-columns: repeat(4, 1fr);
|
|
238
|
+
gap: 20px;
|
|
239
|
+
margin-bottom: 30px;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.stat-card {
|
|
243
|
+
background: var(--bg-secondary);
|
|
244
|
+
border: 1px solid var(--border-color);
|
|
245
|
+
border-radius: 12px;
|
|
246
|
+
padding: 20px;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.stat-icon {
|
|
250
|
+
width: 44px;
|
|
251
|
+
height: 44px;
|
|
252
|
+
border-radius: 10px;
|
|
253
|
+
display: flex;
|
|
254
|
+
align-items: center;
|
|
255
|
+
justify-content: center;
|
|
256
|
+
font-size: 20px;
|
|
257
|
+
margin-bottom: 15px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.stat-icon.orders { background: rgba(99, 102, 241, 0.15); color: var(--accent); }
|
|
261
|
+
.stat-icon.revenue { background: rgba(34, 197, 94, 0.15); color: var(--success); }
|
|
262
|
+
.stat-icon.products { background: rgba(245, 158, 11, 0.15); color: var(--warning); }
|
|
263
|
+
.stat-icon.stores { background: rgba(239, 68, 68, 0.15); color: var(--error); }
|
|
264
|
+
|
|
265
|
+
.stat-value {
|
|
266
|
+
font-size: 28px;
|
|
267
|
+
font-weight: 700;
|
|
268
|
+
margin-bottom: 5px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.stat-label {
|
|
272
|
+
color: var(--text-secondary);
|
|
273
|
+
font-size: 13px;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.stat-change {
|
|
277
|
+
font-size: 12px;
|
|
278
|
+
margin-top: 8px;
|
|
279
|
+
display: flex;
|
|
280
|
+
align-items: center;
|
|
281
|
+
gap: 5px;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.stat-change.positive { color: var(--success); }
|
|
285
|
+
.stat-change.negative { color: var(--error); }
|
|
286
|
+
|
|
287
|
+
/* Content Panels */
|
|
288
|
+
.panels-grid {
|
|
289
|
+
display: grid;
|
|
290
|
+
grid-template-columns: 2fr 1fr;
|
|
291
|
+
gap: 20px;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.panel {
|
|
295
|
+
background: var(--bg-secondary);
|
|
296
|
+
border: 1px solid var(--border-color);
|
|
297
|
+
border-radius: 12px;
|
|
298
|
+
overflow: hidden;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.panel-header {
|
|
302
|
+
padding: 15px 20px;
|
|
303
|
+
border-bottom: 1px solid var(--border-color);
|
|
304
|
+
display: flex;
|
|
305
|
+
justify-content: space-between;
|
|
306
|
+
align-items: center;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.panel-title {
|
|
310
|
+
font-weight: 600;
|
|
311
|
+
font-size: 15px;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.panel-action {
|
|
315
|
+
color: var(--accent);
|
|
316
|
+
font-size: 13px;
|
|
317
|
+
cursor: pointer;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.panel-action:hover {
|
|
321
|
+
text-decoration: underline;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.panel-content {
|
|
325
|
+
padding: 20px;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/* Orders List */
|
|
329
|
+
.order-item {
|
|
330
|
+
display: flex;
|
|
331
|
+
align-items: center;
|
|
332
|
+
padding: 12px 0;
|
|
333
|
+
border-bottom: 1px solid var(--border-color);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.order-item:last-child {
|
|
337
|
+
border-bottom: none;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.order-id {
|
|
341
|
+
font-weight: 600;
|
|
342
|
+
width: 100px;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.order-customer {
|
|
346
|
+
flex: 1;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.order-status {
|
|
350
|
+
padding: 4px 10px;
|
|
351
|
+
border-radius: 20px;
|
|
352
|
+
font-size: 12px;
|
|
353
|
+
font-weight: 500;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.order-status.new { background: rgba(99, 102, 241, 0.15); color: var(--accent); }
|
|
357
|
+
.order-status.preparing { background: rgba(245, 158, 11, 0.15); color: var(--warning); }
|
|
358
|
+
.order-status.shipped { background: rgba(34, 197, 94, 0.15); color: var(--success); }
|
|
359
|
+
.order-status.cancelled { background: rgba(239, 68, 68, 0.15); color: var(--error); }
|
|
360
|
+
|
|
361
|
+
.order-total {
|
|
362
|
+
font-weight: 600;
|
|
363
|
+
width: 100px;
|
|
364
|
+
text-align: right;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.order-date {
|
|
368
|
+
font-size: 12px;
|
|
369
|
+
color: var(--text-secondary);
|
|
370
|
+
width: 100px;
|
|
371
|
+
text-align: right;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* AI Chat Panel */
|
|
375
|
+
.ai-chat-container {
|
|
376
|
+
display: flex;
|
|
377
|
+
flex-direction: column;
|
|
378
|
+
height: 400px;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.ai-messages {
|
|
382
|
+
flex: 1;
|
|
383
|
+
overflow-y: auto;
|
|
384
|
+
padding: 15px;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.ai-message {
|
|
388
|
+
margin-bottom: 15px;
|
|
389
|
+
padding: 12px 15px;
|
|
390
|
+
border-radius: 12px;
|
|
391
|
+
max-width: 85%;
|
|
392
|
+
line-height: 1.5;
|
|
393
|
+
font-size: 14px;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.ai-message.user {
|
|
397
|
+
background: var(--accent);
|
|
398
|
+
color: white;
|
|
399
|
+
margin-left: auto;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.ai-message.bot {
|
|
403
|
+
background: var(--bg-tertiary);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.ai-input-container {
|
|
407
|
+
padding: 15px;
|
|
408
|
+
border-top: 1px solid var(--border-color);
|
|
409
|
+
display: flex;
|
|
410
|
+
gap: 10px;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.ai-input {
|
|
414
|
+
flex: 1;
|
|
415
|
+
background: var(--bg-tertiary);
|
|
416
|
+
border: 1px solid var(--border-color);
|
|
417
|
+
border-radius: 8px;
|
|
418
|
+
padding: 12px 15px;
|
|
419
|
+
color: var(--text-primary);
|
|
420
|
+
font-size: 14px;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.ai-input:focus {
|
|
424
|
+
outline: none;
|
|
425
|
+
border-color: var(--accent);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.ai-send {
|
|
429
|
+
background: var(--accent);
|
|
430
|
+
border: none;
|
|
431
|
+
color: white;
|
|
432
|
+
padding: 12px 20px;
|
|
433
|
+
border-radius: 8px;
|
|
434
|
+
cursor: pointer;
|
|
435
|
+
font-weight: 600;
|
|
436
|
+
transition: all 0.2s;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.ai-send:hover {
|
|
440
|
+
background: var(--accent-hover);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.ai-send:disabled {
|
|
444
|
+
opacity: 0.5;
|
|
445
|
+
cursor: not-allowed;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/* Quick Actions */
|
|
449
|
+
.quick-actions {
|
|
450
|
+
display: flex;
|
|
451
|
+
gap: 10px;
|
|
452
|
+
margin-top: 20px;
|
|
453
|
+
padding: 20px;
|
|
454
|
+
background: var(--bg-secondary);
|
|
455
|
+
border: 1px solid var(--border-color);
|
|
456
|
+
border-radius: 12px;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.quick-action {
|
|
460
|
+
flex: 1;
|
|
461
|
+
display: flex;
|
|
462
|
+
align-items: center;
|
|
463
|
+
justify-content: center;
|
|
464
|
+
gap: 10px;
|
|
465
|
+
padding: 15px;
|
|
466
|
+
background: var(--bg-tertiary);
|
|
467
|
+
border: 1px solid var(--border-color);
|
|
468
|
+
border-radius: 8px;
|
|
469
|
+
cursor: pointer;
|
|
470
|
+
transition: all 0.2s;
|
|
471
|
+
font-weight: 500;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.quick-action:hover {
|
|
475
|
+
border-color: var(--accent);
|
|
476
|
+
background: rgba(99, 102, 241, 0.1);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/* Loading State */
|
|
480
|
+
.loading {
|
|
481
|
+
display: flex;
|
|
482
|
+
flex-direction: column;
|
|
483
|
+
align-items: center;
|
|
484
|
+
justify-content: center;
|
|
485
|
+
height: 200px;
|
|
486
|
+
color: var(--text-secondary);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.spinner {
|
|
490
|
+
width: 40px;
|
|
491
|
+
height: 40px;
|
|
492
|
+
border: 3px solid var(--border-color);
|
|
493
|
+
border-top-color: var(--accent);
|
|
494
|
+
border-radius: 50%;
|
|
495
|
+
animation: spin 1s linear infinite;
|
|
496
|
+
margin-bottom: 15px;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
@keyframes spin {
|
|
500
|
+
to { transform: rotate(360deg); }
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.error-message {
|
|
504
|
+
background: rgba(239, 68, 68, 0.1);
|
|
505
|
+
border: 1px solid var(--error);
|
|
506
|
+
border-radius: 8px;
|
|
507
|
+
padding: 15px;
|
|
508
|
+
color: var(--error);
|
|
509
|
+
text-align: center;
|
|
510
|
+
margin: 10px 0;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.retry-btn {
|
|
514
|
+
margin-top: 10px;
|
|
515
|
+
background: var(--accent);
|
|
516
|
+
border: none;
|
|
517
|
+
color: white;
|
|
518
|
+
padding: 8px 16px;
|
|
519
|
+
border-radius: 6px;
|
|
520
|
+
cursor: pointer;
|
|
521
|
+
font-weight: 500;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.retry-btn:hover {
|
|
525
|
+
background: var(--accent-hover);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/* Page Headers */
|
|
529
|
+
.page-header {
|
|
530
|
+
display: flex;
|
|
531
|
+
justify-content: space-between;
|
|
532
|
+
align-items: center;
|
|
533
|
+
margin-bottom: 25px;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.page-title {
|
|
537
|
+
font-size: 24px;
|
|
538
|
+
font-weight: 600;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
.page-subtitle {
|
|
542
|
+
color: var(--text-secondary);
|
|
543
|
+
font-size: 14px;
|
|
544
|
+
margin-top: 5px;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/* Data Table Styles */
|
|
548
|
+
.data-table {
|
|
549
|
+
width: 100%;
|
|
550
|
+
border-collapse: collapse;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.data-table th,
|
|
554
|
+
.data-table td {
|
|
555
|
+
padding: 12px 15px;
|
|
556
|
+
text-align: left;
|
|
557
|
+
border-bottom: 1px solid var(--border-color);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.data-table th {
|
|
561
|
+
background: var(--bg-tertiary);
|
|
562
|
+
font-weight: 600;
|
|
563
|
+
font-size: 13px;
|
|
564
|
+
color: var(--text-secondary);
|
|
565
|
+
text-transform: uppercase;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.data-table tr:hover td {
|
|
569
|
+
background: rgba(99, 102, 241, 0.05);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/* Card Grid */
|
|
573
|
+
.card-grid {
|
|
574
|
+
display: grid;
|
|
575
|
+
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
576
|
+
gap: 20px;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.card {
|
|
580
|
+
background: var(--bg-secondary);
|
|
581
|
+
border: 1px solid var(--border-color);
|
|
582
|
+
border-radius: 12px;
|
|
583
|
+
padding: 20px;
|
|
584
|
+
transition: all 0.2s;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
.card:hover {
|
|
588
|
+
border-color: var(--accent);
|
|
589
|
+
transform: translateY(-2px);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.card-header {
|
|
593
|
+
display: flex;
|
|
594
|
+
justify-content: space-between;
|
|
595
|
+
align-items: flex-start;
|
|
596
|
+
margin-bottom: 15px;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
.card-title {
|
|
600
|
+
font-weight: 600;
|
|
601
|
+
font-size: 16px;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.card-subtitle {
|
|
605
|
+
font-size: 13px;
|
|
606
|
+
color: var(--text-secondary);
|
|
607
|
+
margin-top: 4px;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
.card-badge {
|
|
611
|
+
padding: 4px 10px;
|
|
612
|
+
border-radius: 20px;
|
|
613
|
+
font-size: 12px;
|
|
614
|
+
font-weight: 500;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
.card-badge.active { background: rgba(34, 197, 94, 0.15); color: var(--success); }
|
|
618
|
+
.card-badge.inactive { background: rgba(239, 68, 68, 0.15); color: var(--error); }
|
|
619
|
+
|
|
620
|
+
.card-stats {
|
|
621
|
+
display: flex;
|
|
622
|
+
gap: 20px;
|
|
623
|
+
margin-top: 15px;
|
|
624
|
+
padding-top: 15px;
|
|
625
|
+
border-top: 1px solid var(--border-color);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
.card-stat {
|
|
629
|
+
text-align: center;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
.card-stat-value {
|
|
633
|
+
font-size: 18px;
|
|
634
|
+
font-weight: 600;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
.card-stat-label {
|
|
638
|
+
font-size: 12px;
|
|
639
|
+
color: var(--text-secondary);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/* Form Styles */
|
|
643
|
+
.form-group {
|
|
644
|
+
margin-bottom: 20px;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
.form-label {
|
|
648
|
+
display: block;
|
|
649
|
+
font-weight: 500;
|
|
650
|
+
margin-bottom: 8px;
|
|
651
|
+
font-size: 14px;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
.form-input {
|
|
655
|
+
width: 100%;
|
|
656
|
+
background: var(--bg-tertiary);
|
|
657
|
+
border: 1px solid var(--border-color);
|
|
658
|
+
border-radius: 8px;
|
|
659
|
+
padding: 12px 15px;
|
|
660
|
+
color: var(--text-primary);
|
|
661
|
+
font-size: 14px;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
.form-input:focus {
|
|
665
|
+
outline: none;
|
|
666
|
+
border-color: var(--accent);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
.form-textarea {
|
|
670
|
+
min-height: 120px;
|
|
671
|
+
resize: vertical;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.form-select {
|
|
675
|
+
appearance: none;
|
|
676
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%23a1a1aa' viewBox='0 0 16 16'%3E%3Cpath d='M8 11L3 6h10l-5 5z'/%3E%3C/svg%3E");
|
|
677
|
+
background-repeat: no-repeat;
|
|
678
|
+
background-position: right 12px center;
|
|
679
|
+
padding-right: 40px;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
.btn-primary {
|
|
683
|
+
background: var(--accent);
|
|
684
|
+
border: none;
|
|
685
|
+
color: white;
|
|
686
|
+
padding: 12px 24px;
|
|
687
|
+
border-radius: 8px;
|
|
688
|
+
cursor: pointer;
|
|
689
|
+
font-weight: 600;
|
|
690
|
+
transition: all 0.2s;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
.btn-primary:hover {
|
|
694
|
+
background: var(--accent-hover);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
.btn-secondary {
|
|
698
|
+
background: var(--bg-tertiary);
|
|
699
|
+
border: 1px solid var(--border-color);
|
|
700
|
+
color: var(--text-primary);
|
|
701
|
+
padding: 12px 24px;
|
|
702
|
+
border-radius: 8px;
|
|
703
|
+
cursor: pointer;
|
|
704
|
+
font-weight: 500;
|
|
705
|
+
transition: all 0.2s;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
.btn-secondary:hover {
|
|
709
|
+
border-color: var(--accent);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/* Settings Page */
|
|
713
|
+
.settings-grid {
|
|
714
|
+
display: grid;
|
|
715
|
+
grid-template-columns: 250px 1fr;
|
|
716
|
+
gap: 30px;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.settings-nav {
|
|
720
|
+
background: var(--bg-secondary);
|
|
721
|
+
border-radius: 12px;
|
|
722
|
+
padding: 15px;
|
|
723
|
+
border: 1px solid var(--border-color);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
.settings-nav-item {
|
|
727
|
+
display: block;
|
|
728
|
+
padding: 12px 15px;
|
|
729
|
+
border-radius: 8px;
|
|
730
|
+
cursor: pointer;
|
|
731
|
+
color: var(--text-secondary);
|
|
732
|
+
transition: all 0.2s;
|
|
733
|
+
margin-bottom: 4px;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
.settings-nav-item:hover {
|
|
737
|
+
background: var(--bg-tertiary);
|
|
738
|
+
color: var(--text-primary);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
.settings-nav-item.active {
|
|
742
|
+
background: var(--accent);
|
|
743
|
+
color: white;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.settings-content {
|
|
747
|
+
background: var(--bg-secondary);
|
|
748
|
+
border-radius: 12px;
|
|
749
|
+
padding: 25px;
|
|
750
|
+
border: 1px solid var(--border-color);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/* Analytics Charts Placeholder */
|
|
754
|
+
.chart-container {
|
|
755
|
+
background: var(--bg-tertiary);
|
|
756
|
+
border-radius: 8px;
|
|
757
|
+
padding: 20px;
|
|
758
|
+
height: 300px;
|
|
759
|
+
display: flex;
|
|
760
|
+
align-items: center;
|
|
761
|
+
justify-content: center;
|
|
762
|
+
color: var(--text-secondary);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
.analytics-grid {
|
|
766
|
+
display: grid;
|
|
767
|
+
grid-template-columns: repeat(2, 1fr);
|
|
768
|
+
gap: 20px;
|
|
769
|
+
margin-bottom: 20px;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/* Help Page */
|
|
773
|
+
.help-section {
|
|
774
|
+
margin-bottom: 30px;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/* Tooltip Styles */
|
|
778
|
+
.tooltip {
|
|
779
|
+
position: relative;
|
|
780
|
+
display: inline-block;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
.tooltip .tooltip-text {
|
|
784
|
+
visibility: hidden;
|
|
785
|
+
opacity: 0;
|
|
786
|
+
background-color: var(--bg-tertiary);
|
|
787
|
+
color: var(--text-primary);
|
|
788
|
+
text-align: center;
|
|
789
|
+
border-radius: 6px;
|
|
790
|
+
padding: 8px 12px;
|
|
791
|
+
position: absolute;
|
|
792
|
+
z-index: 1000;
|
|
793
|
+
bottom: 125%;
|
|
794
|
+
left: 50%;
|
|
795
|
+
transform: translateX(-50%);
|
|
796
|
+
font-size: 12px;
|
|
797
|
+
white-space: nowrap;
|
|
798
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
|
799
|
+
border: 1px solid var(--border-color);
|
|
800
|
+
transition: opacity 0.2s, visibility 0.2s;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
.tooltip .tooltip-text::after {
|
|
804
|
+
content: "";
|
|
805
|
+
position: absolute;
|
|
806
|
+
top: 100%;
|
|
807
|
+
left: 50%;
|
|
808
|
+
margin-left: -5px;
|
|
809
|
+
border-width: 5px;
|
|
810
|
+
border-style: solid;
|
|
811
|
+
border-color: var(--bg-tertiary) transparent transparent transparent;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
.tooltip:hover .tooltip-text {
|
|
815
|
+
visibility: visible;
|
|
816
|
+
opacity: 1;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/* Toast Notification */
|
|
820
|
+
.toast-container {
|
|
821
|
+
position: fixed;
|
|
822
|
+
top: 60px;
|
|
823
|
+
right: 20px;
|
|
824
|
+
z-index: 9999;
|
|
825
|
+
display: flex;
|
|
826
|
+
flex-direction: column;
|
|
827
|
+
gap: 10px;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
.toast {
|
|
831
|
+
background: var(--bg-secondary);
|
|
832
|
+
border: 1px solid var(--border-color);
|
|
833
|
+
border-radius: 8px;
|
|
834
|
+
padding: 15px 20px;
|
|
835
|
+
display: flex;
|
|
836
|
+
align-items: center;
|
|
837
|
+
gap: 12px;
|
|
838
|
+
min-width: 300px;
|
|
839
|
+
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
|
|
840
|
+
animation: slideIn 0.3s ease;
|
|
841
|
+
transition: transform 0.3s, opacity 0.3s;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
.toast.success { border-left: 4px solid var(--success); }
|
|
845
|
+
.toast.error { border-left: 4px solid var(--error); }
|
|
846
|
+
.toast.warning { border-left: 4px solid var(--warning); }
|
|
847
|
+
.toast.info { border-left: 4px solid var(--accent); }
|
|
848
|
+
|
|
849
|
+
@keyframes slideIn {
|
|
850
|
+
from { transform: translateX(100%); opacity: 0; }
|
|
851
|
+
to { transform: translateX(0); opacity: 1; }
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
@keyframes slideOut {
|
|
855
|
+
from { transform: translateX(0); opacity: 1; }
|
|
856
|
+
to { transform: translateX(100%); opacity: 0; }
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
.toast.hiding {
|
|
860
|
+
animation: slideOut 0.3s ease forwards;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
.toast-icon {
|
|
864
|
+
font-size: 20px;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
.toast-content {
|
|
868
|
+
flex: 1;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
.toast-title {
|
|
872
|
+
font-weight: 600;
|
|
873
|
+
font-size: 14px;
|
|
874
|
+
margin-bottom: 2px;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
.toast-message {
|
|
878
|
+
font-size: 13px;
|
|
879
|
+
color: var(--text-secondary);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.toast-close {
|
|
883
|
+
background: none;
|
|
884
|
+
border: none;
|
|
885
|
+
color: var(--text-secondary);
|
|
886
|
+
cursor: pointer;
|
|
887
|
+
padding: 4px;
|
|
888
|
+
font-size: 16px;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/* Skeleton Loading */
|
|
892
|
+
.skeleton {
|
|
893
|
+
background: linear-gradient(90deg, var(--bg-tertiary) 25%, var(--bg-secondary) 50%, var(--bg-tertiary) 75%);
|
|
894
|
+
background-size: 200% 100%;
|
|
895
|
+
animation: shimmer 1.5s infinite;
|
|
896
|
+
border-radius: 4px;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
@keyframes shimmer {
|
|
900
|
+
0% { background-position: 200% 0; }
|
|
901
|
+
100% { background-position: -200% 0; }
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
.skeleton-text {
|
|
905
|
+
height: 14px;
|
|
906
|
+
margin-bottom: 8px;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
.skeleton-title {
|
|
910
|
+
height: 20px;
|
|
911
|
+
width: 60%;
|
|
912
|
+
margin-bottom: 12px;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
.skeleton-avatar {
|
|
916
|
+
width: 40px;
|
|
917
|
+
height: 40px;
|
|
918
|
+
border-radius: 50%;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
.skeleton-card {
|
|
922
|
+
padding: 20px;
|
|
923
|
+
background: var(--bg-secondary);
|
|
924
|
+
border: 1px solid var(--border-color);
|
|
925
|
+
border-radius: 12px;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
/* Page Transition */
|
|
929
|
+
.page {
|
|
930
|
+
display: none;
|
|
931
|
+
padding: 25px;
|
|
932
|
+
overflow-y: auto;
|
|
933
|
+
flex: 1;
|
|
934
|
+
opacity: 0;
|
|
935
|
+
transform: translateY(10px);
|
|
936
|
+
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.page.active {
|
|
940
|
+
display: block;
|
|
941
|
+
opacity: 1;
|
|
942
|
+
transform: translateY(0);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/* Modal Styles */
|
|
946
|
+
.modal-overlay {
|
|
947
|
+
position: fixed;
|
|
948
|
+
top: 0;
|
|
949
|
+
left: 0;
|
|
950
|
+
right: 0;
|
|
951
|
+
bottom: 0;
|
|
952
|
+
background: rgba(0, 0, 0, 0.7);
|
|
953
|
+
display: flex;
|
|
954
|
+
align-items: center;
|
|
955
|
+
justify-content: center;
|
|
956
|
+
z-index: 2000;
|
|
957
|
+
opacity: 0;
|
|
958
|
+
visibility: hidden;
|
|
959
|
+
transition: opacity 0.3s, visibility 0.3s;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
.modal-overlay.active {
|
|
963
|
+
opacity: 1;
|
|
964
|
+
visibility: visible;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
.modal {
|
|
968
|
+
background: var(--bg-secondary);
|
|
969
|
+
border: 1px solid var(--border-color);
|
|
970
|
+
border-radius: 12px;
|
|
971
|
+
width: 90%;
|
|
972
|
+
max-width: 500px;
|
|
973
|
+
max-height: 90vh;
|
|
974
|
+
overflow-y: auto;
|
|
975
|
+
transform: scale(0.9);
|
|
976
|
+
transition: transform 0.3s;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.modal-overlay.active .modal {
|
|
980
|
+
transform: scale(1);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
.modal-header {
|
|
984
|
+
padding: 20px;
|
|
985
|
+
border-bottom: 1px solid var(--border-color);
|
|
986
|
+
display: flex;
|
|
987
|
+
justify-content: space-between;
|
|
988
|
+
align-items: center;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
.modal-title {
|
|
992
|
+
font-size: 18px;
|
|
993
|
+
font-weight: 600;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
.modal-close {
|
|
997
|
+
background: none;
|
|
998
|
+
border: none;
|
|
999
|
+
color: var(--text-secondary);
|
|
1000
|
+
cursor: pointer;
|
|
1001
|
+
font-size: 24px;
|
|
1002
|
+
padding: 4px;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
.modal-close:hover {
|
|
1006
|
+
color: var(--text-primary);
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
.modal-body {
|
|
1010
|
+
padding: 20px;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
.modal-footer {
|
|
1014
|
+
padding: 20px;
|
|
1015
|
+
border-top: 1px solid var(--border-color);
|
|
1016
|
+
display: flex;
|
|
1017
|
+
justify-content: flex-end;
|
|
1018
|
+
gap: 10px;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/* Store Card Enhanced */
|
|
1022
|
+
.store-card {
|
|
1023
|
+
background: var(--bg-secondary);
|
|
1024
|
+
border: 1px solid var(--border-color);
|
|
1025
|
+
border-radius: 12px;
|
|
1026
|
+
padding: 20px;
|
|
1027
|
+
transition: all 0.2s;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
.store-card:hover {
|
|
1031
|
+
border-color: var(--accent);
|
|
1032
|
+
transform: translateY(-2px);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
.store-card-header {
|
|
1036
|
+
display: flex;
|
|
1037
|
+
justify-content: space-between;
|
|
1038
|
+
align-items: flex-start;
|
|
1039
|
+
margin-bottom: 15px;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
.store-platform-icon {
|
|
1043
|
+
width: 48px;
|
|
1044
|
+
height: 48px;
|
|
1045
|
+
border-radius: 10px;
|
|
1046
|
+
display: flex;
|
|
1047
|
+
align-items: center;
|
|
1048
|
+
justify-content: center;
|
|
1049
|
+
font-size: 24px;
|
|
1050
|
+
background: var(--bg-tertiary);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
.store-actions {
|
|
1054
|
+
display: flex;
|
|
1055
|
+
gap: 8px;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
.store-action-btn {
|
|
1059
|
+
background: var(--bg-tertiary);
|
|
1060
|
+
border: 1px solid var(--border-color);
|
|
1061
|
+
border-radius: 6px;
|
|
1062
|
+
padding: 8px 12px;
|
|
1063
|
+
cursor: pointer;
|
|
1064
|
+
color: var(--text-secondary);
|
|
1065
|
+
transition: all 0.2s;
|
|
1066
|
+
font-size: 14px;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
.store-action-btn:hover {
|
|
1070
|
+
background: var(--accent);
|
|
1071
|
+
color: white;
|
|
1072
|
+
border-color: var(--accent);
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
.store-action-btn.delete:hover {
|
|
1076
|
+
background: var(--error);
|
|
1077
|
+
border-color: var(--error);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
/* Toggle Switch */
|
|
1081
|
+
.toggle-switch {
|
|
1082
|
+
position: relative;
|
|
1083
|
+
width: 48px;
|
|
1084
|
+
height: 26px;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
.toggle-switch input {
|
|
1088
|
+
opacity: 0;
|
|
1089
|
+
width: 0;
|
|
1090
|
+
height: 0;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
.toggle-slider {
|
|
1094
|
+
position: absolute;
|
|
1095
|
+
cursor: pointer;
|
|
1096
|
+
top: 0;
|
|
1097
|
+
left: 0;
|
|
1098
|
+
right: 0;
|
|
1099
|
+
bottom: 0;
|
|
1100
|
+
background-color: var(--bg-tertiary);
|
|
1101
|
+
border: 1px solid var(--border-color);
|
|
1102
|
+
transition: 0.3s;
|
|
1103
|
+
border-radius: 26px;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
.toggle-slider:before {
|
|
1107
|
+
position: absolute;
|
|
1108
|
+
content: "";
|
|
1109
|
+
height: 20px;
|
|
1110
|
+
width: 20px;
|
|
1111
|
+
left: 2px;
|
|
1112
|
+
bottom: 2px;
|
|
1113
|
+
background-color: var(--text-secondary);
|
|
1114
|
+
transition: 0.3s;
|
|
1115
|
+
border-radius: 50%;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
.toggle-switch input:checked + .toggle-slider {
|
|
1119
|
+
background-color: var(--accent);
|
|
1120
|
+
border-color: var(--accent);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
.toggle-switch input:checked + .toggle-slider:before {
|
|
1124
|
+
transform: translateX(22px);
|
|
1125
|
+
background-color: white;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
/* Platform Grid */
|
|
1129
|
+
.platform-grid {
|
|
1130
|
+
display: grid;
|
|
1131
|
+
grid-template-columns: repeat(3, 1fr);
|
|
1132
|
+
gap: 12px;
|
|
1133
|
+
margin-bottom: 20px;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
.platform-option {
|
|
1137
|
+
background: var(--bg-tertiary);
|
|
1138
|
+
border: 2px solid var(--border-color);
|
|
1139
|
+
border-radius: 10px;
|
|
1140
|
+
padding: 15px;
|
|
1141
|
+
text-align: center;
|
|
1142
|
+
cursor: pointer;
|
|
1143
|
+
transition: all 0.2s;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
.platform-option:hover {
|
|
1147
|
+
border-color: var(--accent);
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
.platform-option.selected {
|
|
1151
|
+
border-color: var(--accent);
|
|
1152
|
+
background: rgba(99, 102, 241, 0.1);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
.platform-option-icon {
|
|
1156
|
+
font-size: 28px;
|
|
1157
|
+
margin-bottom: 8px;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
.platform-option-name {
|
|
1161
|
+
font-size: 13px;
|
|
1162
|
+
font-weight: 500;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/* Error Boundary */
|
|
1166
|
+
.error-boundary {
|
|
1167
|
+
display: flex;
|
|
1168
|
+
flex-direction: column;
|
|
1169
|
+
align-items: center;
|
|
1170
|
+
justify-content: center;
|
|
1171
|
+
padding: 60px 20px;
|
|
1172
|
+
text-align: center;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
.error-boundary-icon {
|
|
1176
|
+
font-size: 64px;
|
|
1177
|
+
margin-bottom: 20px;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.error-boundary-title {
|
|
1181
|
+
font-size: 24px;
|
|
1182
|
+
font-weight: 600;
|
|
1183
|
+
margin-bottom: 10px;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
.error-boundary-message {
|
|
1187
|
+
color: var(--text-secondary);
|
|
1188
|
+
margin-bottom: 20px;
|
|
1189
|
+
max-width: 400px;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
/* Dialog */
|
|
1193
|
+
.dialog-overlay {
|
|
1194
|
+
position: fixed;
|
|
1195
|
+
top: 0;
|
|
1196
|
+
left: 0;
|
|
1197
|
+
right: 0;
|
|
1198
|
+
bottom: 0;
|
|
1199
|
+
background: rgba(0, 0, 0, 0.7);
|
|
1200
|
+
display: flex;
|
|
1201
|
+
align-items: center;
|
|
1202
|
+
justify-content: center;
|
|
1203
|
+
z-index: 3000;
|
|
1204
|
+
opacity: 0;
|
|
1205
|
+
visibility: hidden;
|
|
1206
|
+
transition: opacity 0.3s, visibility 0.3s;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
.dialog-overlay.active {
|
|
1210
|
+
opacity: 1;
|
|
1211
|
+
visibility: visible;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
.dialog {
|
|
1215
|
+
background: var(--bg-secondary);
|
|
1216
|
+
border: 1px solid var(--border-color);
|
|
1217
|
+
border-radius: 12px;
|
|
1218
|
+
width: 90%;
|
|
1219
|
+
max-width: 400px;
|
|
1220
|
+
padding: 25px;
|
|
1221
|
+
text-align: center;
|
|
1222
|
+
transform: scale(0.9);
|
|
1223
|
+
transition: transform 0.3s;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
.dialog-overlay.active .dialog {
|
|
1227
|
+
transform: scale(1);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
.dialog-icon {
|
|
1231
|
+
font-size: 48px;
|
|
1232
|
+
margin-bottom: 15px;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
.dialog-title {
|
|
1236
|
+
font-size: 20px;
|
|
1237
|
+
font-weight: 600;
|
|
1238
|
+
margin-bottom: 10px;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
.dialog-message {
|
|
1242
|
+
color: var(--text-secondary);
|
|
1243
|
+
margin-bottom: 25px;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
.dialog-buttons {
|
|
1247
|
+
display: flex;
|
|
1248
|
+
gap: 10px;
|
|
1249
|
+
justify-content: center;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
/* Responsive */
|
|
1253
|
+
@media (max-width: 1024px) {
|
|
1254
|
+
.sidebar {
|
|
1255
|
+
width: 70px;
|
|
1256
|
+
}
|
|
1257
|
+
.sidebar-header, .nav-section-title, .nav-item span:not(.nav-icon) {
|
|
1258
|
+
display: none;
|
|
1259
|
+
}
|
|
1260
|
+
.nav-item {
|
|
1261
|
+
justify-content: center;
|
|
1262
|
+
padding: 12px;
|
|
1263
|
+
}
|
|
1264
|
+
.sidebar-header {
|
|
1265
|
+
padding: 15px 10px;
|
|
1266
|
+
}
|
|
1267
|
+
.user-info {
|
|
1268
|
+
justify-content: center;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
@media (max-width: 768px) {
|
|
1273
|
+
.stats-grid {
|
|
1274
|
+
grid-template-columns: repeat(2, 1fr);
|
|
1275
|
+
}
|
|
1276
|
+
.panels-grid {
|
|
1277
|
+
grid-template-columns: 1fr;
|
|
1278
|
+
}
|
|
1279
|
+
.platform-grid {
|
|
1280
|
+
grid-template-columns: repeat(2, 1fr);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
@media (max-width: 480px) {
|
|
1285
|
+
.stats-grid {
|
|
1286
|
+
grid-template-columns: 1fr;
|
|
1287
|
+
}
|
|
1288
|
+
.quick-actions {
|
|
1289
|
+
flex-direction: column;
|
|
1290
|
+
}
|
|
1291
|
+
.modal {
|
|
1292
|
+
width: 95%;
|
|
1293
|
+
margin: 10px;
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
.help-title {
|
|
1298
|
+
font-size: 18px;
|
|
1299
|
+
font-weight: 600;
|
|
1300
|
+
margin-bottom: 15px;
|
|
1301
|
+
color: var(--accent);
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
.help-item {
|
|
1305
|
+
background: var(--bg-secondary);
|
|
1306
|
+
border: 1px solid var(--border-color);
|
|
1307
|
+
border-radius: 8px;
|
|
1308
|
+
padding: 15px;
|
|
1309
|
+
margin-bottom: 10px;
|
|
1310
|
+
cursor: pointer;
|
|
1311
|
+
transition: all 0.2s;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
.help-item:hover {
|
|
1315
|
+
border-color: var(--accent);
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
.help-question {
|
|
1319
|
+
font-weight: 500;
|
|
1320
|
+
margin-bottom: 8px;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
.help-answer {
|
|
1324
|
+
font-size: 14px;
|
|
1325
|
+
color: var(--text-secondary);
|
|
1326
|
+
display: none;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
.help-item.expanded .help-answer {
|
|
1330
|
+
display: block;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
/* Responsive */
|
|
1334
|
+
@media (max-width: 1200px) {
|
|
1335
|
+
.stats-grid {
|
|
1336
|
+
grid-template-columns: repeat(2, 1fr);
|
|
1337
|
+
}
|
|
1338
|
+
.panels-grid {
|
|
1339
|
+
grid-template-columns: 1fr;
|
|
1340
|
+
}
|
|
1341
|
+
.analytics-grid {
|
|
1342
|
+
grid-template-columns: 1fr;
|
|
1343
|
+
}
|
|
1344
|
+
.settings-grid {
|
|
1345
|
+
grid-template-columns: 1fr;
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
</style>
|
|
1349
|
+
</head>
|
|
1350
|
+
<body>
|
|
1351
|
+
<div class="titlebar">
|
|
1352
|
+
<div class="titlebar-left">
|
|
1353
|
+
<span class="logo">🐙 VANTUZ</span>
|
|
1354
|
+
</div>
|
|
1355
|
+
<div class="titlebar-right">
|
|
1356
|
+
<button class="window-btn" onclick="window.vantuz.minimize()">─</button>
|
|
1357
|
+
<button class="window-btn" onclick="window.vantuz.maximize()">□</button>
|
|
1358
|
+
<button class="window-btn close" onclick="window.vantuz.close()">✕</button>
|
|
1359
|
+
</div>
|
|
1360
|
+
</div>
|
|
1361
|
+
|
|
1362
|
+
<div class="app-container">
|
|
1363
|
+
<!-- Sidebar -->
|
|
1364
|
+
<div class="sidebar">
|
|
1365
|
+
<div class="sidebar-header">
|
|
1366
|
+
<div style="color: var(--accent); font-size: 12px; font-weight: 600;">ENTERPRISE</div>
|
|
1367
|
+
<div class="user-info" id="user-info">
|
|
1368
|
+
<div class="loading">
|
|
1369
|
+
<div class="spinner"></div>
|
|
1370
|
+
</div>
|
|
1371
|
+
</div>
|
|
1372
|
+
</div>
|
|
1373
|
+
|
|
1374
|
+
<div class="sidebar-nav">
|
|
1375
|
+
<div class="nav-section">
|
|
1376
|
+
<div class="nav-section-title">Ana Sayfa</div>
|
|
1377
|
+
<div class="nav-item active tooltip" onclick="showPage('dashboard')">
|
|
1378
|
+
<span class="nav-icon">📊</span>
|
|
1379
|
+
<span>Dashboard</span>
|
|
1380
|
+
<span class="tooltip-text">Ana Dashboard</span>
|
|
1381
|
+
</div>
|
|
1382
|
+
</div>
|
|
1383
|
+
|
|
1384
|
+
<div class="nav-section">
|
|
1385
|
+
<div class="nav-section-title">Yönetim</div>
|
|
1386
|
+
<div class="nav-item tooltip" onclick="showPage('orders')">
|
|
1387
|
+
<span class="nav-icon">📦</span>
|
|
1388
|
+
<span>Siparişler</span>
|
|
1389
|
+
<span class="tooltip-text">Sipariş Yönetimi</span>
|
|
1390
|
+
<span class="nav-badge" id="order-badge">0</span>
|
|
1391
|
+
</div>
|
|
1392
|
+
<div class="nav-item tooltip" onclick="showPage('products')">
|
|
1393
|
+
<span class="nav-icon">🛍️</span>
|
|
1394
|
+
<span>Ürünler</span>
|
|
1395
|
+
<span class="tooltip-text">Ürün Envanteri</span>
|
|
1396
|
+
</div>
|
|
1397
|
+
<div class="nav-item tooltip" onclick="showPage('stores')">
|
|
1398
|
+
<span class="nav-icon">🏪</span>
|
|
1399
|
+
<span>Mağazalar</span>
|
|
1400
|
+
<span class="tooltip-text">Mağaza Yönetimi</span>
|
|
1401
|
+
</div>
|
|
1402
|
+
</div>
|
|
1403
|
+
|
|
1404
|
+
<div class="nav-section">
|
|
1405
|
+
<div class="nav-section-title">AI Asistan</div>
|
|
1406
|
+
<div class="nav-item tooltip" onclick="showPage('chat')">
|
|
1407
|
+
<span class="nav-icon">💬</span>
|
|
1408
|
+
<span>Sohbet</span>
|
|
1409
|
+
<span class="tooltip-text">AI ile Sohbet</span>
|
|
1410
|
+
</div>
|
|
1411
|
+
<div class="nav-item tooltip" onclick="showPage('analytics')">
|
|
1412
|
+
<span class="nav-icon">📈</span>
|
|
1413
|
+
<span>Analiz</span>
|
|
1414
|
+
<span class="tooltip-text">Satış Analizleri</span>
|
|
1415
|
+
</div>
|
|
1416
|
+
</div>
|
|
1417
|
+
|
|
1418
|
+
<div class="nav-section">
|
|
1419
|
+
<div class="nav-section-title">Sistem</div>
|
|
1420
|
+
<div class="nav-item tooltip" onclick="showPage('settings')">
|
|
1421
|
+
<span class="nav-icon">⚙️</span>
|
|
1422
|
+
<span>Ayarlar</span>
|
|
1423
|
+
<span class="tooltip-text">Uygulama Ayarları</span>
|
|
1424
|
+
</div>
|
|
1425
|
+
<div class="nav-item tooltip" onclick="showPage('help')">
|
|
1426
|
+
<span class="nav-icon">❓</span>
|
|
1427
|
+
<span>Yardım</span>
|
|
1428
|
+
<span class="tooltip-text">Yardım & Destek</span>
|
|
1429
|
+
</div>
|
|
1430
|
+
</div>
|
|
1431
|
+
</div>
|
|
1432
|
+
</div>
|
|
1433
|
+
|
|
1434
|
+
<!-- Main Content -->
|
|
1435
|
+
<div class="main-content">
|
|
1436
|
+
<!-- Dashboard Page -->
|
|
1437
|
+
<div class="page active" id="page-dashboard">
|
|
1438
|
+
<div class="dashboard-header">
|
|
1439
|
+
<div>
|
|
1440
|
+
<div class="dashboard-title" id="dashboard-title">Hoş Geldin! 👋</div>
|
|
1441
|
+
<div class="dashboard-subtitle" id="dashboard-subtitle">Yükleniyor...</div>
|
|
1442
|
+
</div>
|
|
1443
|
+
<button class="btn-primary" onclick="refreshDashboard()">🔄 Yenile</button>
|
|
1444
|
+
</div>
|
|
1445
|
+
|
|
1446
|
+
<!-- Stats -->
|
|
1447
|
+
<div class="stats-grid" id="stats-grid">
|
|
1448
|
+
<div class="stat-card">
|
|
1449
|
+
<div class="stat-icon orders">📦</div>
|
|
1450
|
+
<div class="loading"><div class="spinner"></div></div>
|
|
1451
|
+
</div>
|
|
1452
|
+
<div class="stat-card">
|
|
1453
|
+
<div class="stat-icon revenue">💰</div>
|
|
1454
|
+
<div class="loading"><div class="spinner"></div></div>
|
|
1455
|
+
</div>
|
|
1456
|
+
<div class="stat-card">
|
|
1457
|
+
<div class="stat-icon products">🛍️</div>
|
|
1458
|
+
<div class="loading"><div class="spinner"></div></div>
|
|
1459
|
+
</div>
|
|
1460
|
+
<div class="stat-card">
|
|
1461
|
+
<div class="stat-icon stores">🏪</div>
|
|
1462
|
+
<div class="loading"><div class="spinner"></div></div>
|
|
1463
|
+
</div>
|
|
1464
|
+
</div>
|
|
1465
|
+
|
|
1466
|
+
<!-- Panels -->
|
|
1467
|
+
<div class="panels-grid">
|
|
1468
|
+
<!-- Recent Orders -->
|
|
1469
|
+
<div class="panel">
|
|
1470
|
+
<div class="panel-header">
|
|
1471
|
+
<div class="panel-title">Son Siparişler</div>
|
|
1472
|
+
<div class="panel-action" onclick="showPage('orders')">Tümünü Gör →</div>
|
|
1473
|
+
</div>
|
|
1474
|
+
<div class="panel-content" id="recent-orders">
|
|
1475
|
+
<div class="loading"><div class="spinner"></div></div>
|
|
1476
|
+
</div>
|
|
1477
|
+
</div>
|
|
1478
|
+
|
|
1479
|
+
<!-- AI Chat -->
|
|
1480
|
+
<div class="panel">
|
|
1481
|
+
<div class="panel-header">
|
|
1482
|
+
<div class="panel-title">💬 Vantuz AI</div>
|
|
1483
|
+
</div>
|
|
1484
|
+
<div class="ai-chat-container">
|
|
1485
|
+
<div class="ai-messages" id="ai-messages">
|
|
1486
|
+
<div class="ai-message bot">
|
|
1487
|
+
Merhaba! Ben Vantuz AI asistanınızım.
|
|
1488
|
+
Size nasıl yardımcı olabilirim?
|
|
1489
|
+
<br><br>
|
|
1490
|
+
📦 Sipariş durumlarını kontrol edebilirim
|
|
1491
|
+
<br>
|
|
1492
|
+
📊 Satış raporları hazırlayabilirim
|
|
1493
|
+
<br>
|
|
1494
|
+
🛍️ Ürün önerileri yapabilirim
|
|
1495
|
+
</div>
|
|
1496
|
+
</div>
|
|
1497
|
+
<div class="ai-input-container">
|
|
1498
|
+
<input type="text" class="ai-input" id="ai-input" placeholder="Mesajınızı yazın..." onkeypress="if(event.key==='Enter') sendMessage()">
|
|
1499
|
+
<button class="ai-send" id="ai-send" onclick="sendMessage()">Gönder</button>
|
|
1500
|
+
</div>
|
|
1501
|
+
</div>
|
|
1502
|
+
</div>
|
|
1503
|
+
</div>
|
|
1504
|
+
|
|
1505
|
+
<!-- Quick Actions -->
|
|
1506
|
+
<div class="quick-actions">
|
|
1507
|
+
<div class="quick-action" onclick="showPage('products')">
|
|
1508
|
+
<span>👁️</span>
|
|
1509
|
+
<span>AI Vision ile Ürün Ekle</span>
|
|
1510
|
+
</div>
|
|
1511
|
+
<div class="quick-action" onclick="showPage('analytics')">
|
|
1512
|
+
<span>📈</span>
|
|
1513
|
+
<span>Pazar Analizi Yap</span>
|
|
1514
|
+
</div>
|
|
1515
|
+
<div class="quick-action" onclick="showPage('chat')">
|
|
1516
|
+
<span>👥</span>
|
|
1517
|
+
<span>Ekip Toplantısı</span>
|
|
1518
|
+
</div>
|
|
1519
|
+
<div class="quick-action" onclick="showPage('stores')">
|
|
1520
|
+
<span>🔄</span>
|
|
1521
|
+
<span>Stok Senkronize Et</span>
|
|
1522
|
+
</div>
|
|
1523
|
+
</div>
|
|
1524
|
+
</div>
|
|
1525
|
+
|
|
1526
|
+
<!-- Orders Page -->
|
|
1527
|
+
<div class="page" id="page-orders">
|
|
1528
|
+
<div class="page-header">
|
|
1529
|
+
<div>
|
|
1530
|
+
<div class="page-title">📦 Siparişler</div>
|
|
1531
|
+
<div class="page-subtitle">Tüm siparişlerinizi buradan yönetebilirsiniz</div>
|
|
1532
|
+
</div>
|
|
1533
|
+
<button class="btn-primary" onclick="refreshOrders()">🔄 Yenile</button>
|
|
1534
|
+
</div>
|
|
1535
|
+
<div class="panel">
|
|
1536
|
+
<div class="panel-content" id="orders-list">
|
|
1537
|
+
<div class="loading"><div class="spinner"></div></div>
|
|
1538
|
+
</div>
|
|
1539
|
+
</div>
|
|
1540
|
+
</div>
|
|
1541
|
+
|
|
1542
|
+
<!-- Products Page -->
|
|
1543
|
+
<div class="page" id="page-products">
|
|
1544
|
+
<div class="page-header">
|
|
1545
|
+
<div>
|
|
1546
|
+
<div class="page-title">🛍️ Ürünler</div>
|
|
1547
|
+
<div class="page-subtitle">Ürün envanterinizi buradan yönetebilirsiniz</div>
|
|
1548
|
+
</div>
|
|
1549
|
+
<button class="btn-primary" onclick="refreshProducts()">🔄 Yenile</button>
|
|
1550
|
+
</div>
|
|
1551
|
+
<div class="card-grid" id="products-grid">
|
|
1552
|
+
<div class="loading"><div class="spinner"></div></div>
|
|
1553
|
+
</div>
|
|
1554
|
+
</div>
|
|
1555
|
+
|
|
1556
|
+
<!-- Stores Page -->
|
|
1557
|
+
<div class="page" id="page-stores">
|
|
1558
|
+
<div class="page-header">
|
|
1559
|
+
<div>
|
|
1560
|
+
<div class="page-title">🏪 Mağazalar</div>
|
|
1561
|
+
<div class="page-subtitle">Bağlı mağazalarınızı buradan yönetebilirsiniz</div>
|
|
1562
|
+
</div>
|
|
1563
|
+
<button class="btn-primary" onclick="openAddStoreModal()">➕ Mağaza Ekle</button>
|
|
1564
|
+
</div>
|
|
1565
|
+
|
|
1566
|
+
<!-- Stores Stats -->
|
|
1567
|
+
<div class="stats-grid" id="stores-stats" style="grid-template-columns: repeat(3, 1fr); margin-bottom: 25px;">
|
|
1568
|
+
<div class="stat-card">
|
|
1569
|
+
<div class="stat-icon" style="background: rgba(99, 102, 241, 0.15); color: var(--accent);">🏪</div>
|
|
1570
|
+
<div class="stat-value" id="total-stores">-</div>
|
|
1571
|
+
<div class="stat-label">Toplam Mağaza</div>
|
|
1572
|
+
</div>
|
|
1573
|
+
<div class="stat-card">
|
|
1574
|
+
<div class="stat-icon" style="background: rgba(34, 197, 94, 0.15); color: var(--success);">✅</div>
|
|
1575
|
+
<div class="stat-value" id="active-stores">-</div>
|
|
1576
|
+
<div class="stat-label">Aktif Mağaza</div>
|
|
1577
|
+
</div>
|
|
1578
|
+
<div class="stat-card">
|
|
1579
|
+
<div class="stat-icon" style="background: rgba(239, 68, 68, 0.15); color: var(--error);">⏸️</div>
|
|
1580
|
+
<div class="stat-value" id="inactive-stores">-</div>
|
|
1581
|
+
<div class="stat-label">Pasif Mağaza</div>
|
|
1582
|
+
</div>
|
|
1583
|
+
</div>
|
|
1584
|
+
|
|
1585
|
+
<div class="card-grid" id="stores-grid">
|
|
1586
|
+
<!-- Skeleton loading -->
|
|
1587
|
+
<div class="skeleton-card">
|
|
1588
|
+
<div class="skeleton skeleton-title"></div>
|
|
1589
|
+
<div class="skeleton skeleton-text"></div>
|
|
1590
|
+
<div class="skeleton skeleton-text" style="width: 60%;"></div>
|
|
1591
|
+
</div>
|
|
1592
|
+
<div class="skeleton-card">
|
|
1593
|
+
<div class="skeleton skeleton-title"></div>
|
|
1594
|
+
<div class="skeleton skeleton-text"></div>
|
|
1595
|
+
<div class="skeleton skeleton-text" style="width: 60%;"></div>
|
|
1596
|
+
</div>
|
|
1597
|
+
</div>
|
|
1598
|
+
</div>
|
|
1599
|
+
|
|
1600
|
+
<!-- Chat Page -->
|
|
1601
|
+
<div class="page" id="page-chat">
|
|
1602
|
+
<div class="page-header">
|
|
1603
|
+
<div>
|
|
1604
|
+
<div class="page-title">💬 AI Sohbet</div>
|
|
1605
|
+
<div class="page-subtitle">Vantuz AI ile sohbet edin</div>
|
|
1606
|
+
</div>
|
|
1607
|
+
</div>
|
|
1608
|
+
<div class="panel" style="height: calc(100vh - 180px); display: flex; flex-direction: column;">
|
|
1609
|
+
<div class="ai-chat-container" style="flex: 1;">
|
|
1610
|
+
<div class="ai-messages" id="chat-page-messages">
|
|
1611
|
+
<div class="ai-message bot">
|
|
1612
|
+
Merhaba! Ben Vantuz AI asistanınızım.
|
|
1613
|
+
Size nasıl yardımcı olabilirim?
|
|
1614
|
+
</div>
|
|
1615
|
+
</div>
|
|
1616
|
+
<div class="ai-input-container">
|
|
1617
|
+
<input type="text" class="ai-input" id="chat-page-input" placeholder="Mesajınızı yazın..." onkeypress="if(event.key==='Enter') sendChatPageMessage()">
|
|
1618
|
+
<button class="ai-send" id="chat-page-send" onclick="sendChatPageMessage()">Gönder</button>
|
|
1619
|
+
</div>
|
|
1620
|
+
</div>
|
|
1621
|
+
</div>
|
|
1622
|
+
</div>
|
|
1623
|
+
|
|
1624
|
+
<!-- Analytics Page -->
|
|
1625
|
+
<div class="page" id="page-analytics">
|
|
1626
|
+
<div class="page-header">
|
|
1627
|
+
<div>
|
|
1628
|
+
<div class="page-title">📈 Analiz</div>
|
|
1629
|
+
<div class="page-subtitle">Satış ve performans analizleriniz</div>
|
|
1630
|
+
</div>
|
|
1631
|
+
<button class="btn-primary" onclick="refreshAnalytics()">🔄 Yenile</button>
|
|
1632
|
+
</div>
|
|
1633
|
+
<div class="analytics-grid">
|
|
1634
|
+
<div class="panel">
|
|
1635
|
+
<div class="panel-header">
|
|
1636
|
+
<div class="panel-title">Satış Grafiği</div>
|
|
1637
|
+
</div>
|
|
1638
|
+
<div class="panel-content">
|
|
1639
|
+
<div class="chart-container">
|
|
1640
|
+
📊 Satış verileri burada görüntülenecek
|
|
1641
|
+
</div>
|
|
1642
|
+
</div>
|
|
1643
|
+
</div>
|
|
1644
|
+
<div class="panel">
|
|
1645
|
+
<div class="panel-header">
|
|
1646
|
+
<div class="panel-title">Ürün Performansı</div>
|
|
1647
|
+
</div>
|
|
1648
|
+
<div class="panel-content">
|
|
1649
|
+
<div class="chart-container">
|
|
1650
|
+
📈 Ürün satış istatistikleri burada
|
|
1651
|
+
</div>
|
|
1652
|
+
</div>
|
|
1653
|
+
</div>
|
|
1654
|
+
</div>
|
|
1655
|
+
<div class="panel">
|
|
1656
|
+
<div class="panel-header">
|
|
1657
|
+
<div class="panel-title">Özet Metrikler</div>
|
|
1658
|
+
</div>
|
|
1659
|
+
<div class="panel-content">
|
|
1660
|
+
<div class="stats-grid" style="grid-template-columns: repeat(4, 1fr);">
|
|
1661
|
+
<div class="stat-card">
|
|
1662
|
+
<div class="stat-value" id="analytics-orders">-</div>
|
|
1663
|
+
<div class="stat-label">Toplam Sipariş</div>
|
|
1664
|
+
</div>
|
|
1665
|
+
<div class="stat-card">
|
|
1666
|
+
<div class="stat-value" id="analytics-revenue">-</div>
|
|
1667
|
+
<div class="stat-label">Toplam Ciro</div>
|
|
1668
|
+
</div>
|
|
1669
|
+
<div class="stat-card">
|
|
1670
|
+
<div class="stat-value" id="analytics-products">-</div>
|
|
1671
|
+
<div class="stat-label">Aktif Ürün</div>
|
|
1672
|
+
</div>
|
|
1673
|
+
<div class="stat-card">
|
|
1674
|
+
<div class="stat-value" id="analytics-stores">-</div>
|
|
1675
|
+
<div class="stat-label">Mağaza</div>
|
|
1676
|
+
</div>
|
|
1677
|
+
</div>
|
|
1678
|
+
</div>
|
|
1679
|
+
</div>
|
|
1680
|
+
</div>
|
|
1681
|
+
|
|
1682
|
+
<!-- Settings Page -->
|
|
1683
|
+
<div class="page" id="page-settings">
|
|
1684
|
+
<div class="page-header">
|
|
1685
|
+
<div>
|
|
1686
|
+
<div class="page-title">⚙️ Ayarlar</div>
|
|
1687
|
+
<div class="page-subtitle">Uygulama ayarlarınızı buradan yapabilirsiniz</div>
|
|
1688
|
+
</div>
|
|
1689
|
+
</div>
|
|
1690
|
+
<div class="settings-grid">
|
|
1691
|
+
<div class="settings-nav">
|
|
1692
|
+
<div class="settings-nav-item active" onclick="showSettingsTab('general')">Genel</div>
|
|
1693
|
+
<div class="settings-nav-item" onclick="showSettingsTab('account')">Hesap</div>
|
|
1694
|
+
<div class="settings-nav-item" onclick="showSettingsTab('ai')">AI Ayarları</div>
|
|
1695
|
+
<div class="settings-nav-item" onclick="showSettingsTab('notifications')">Bildirimler</div>
|
|
1696
|
+
</div>
|
|
1697
|
+
<div class="settings-content" id="settings-content">
|
|
1698
|
+
<div id="settings-general" class="settings-tab active">
|
|
1699
|
+
<h3 style="margin-bottom: 20px;">Genel Ayarlar</h3>
|
|
1700
|
+
<div class="form-group">
|
|
1701
|
+
<label class="form-label">Uygulama Dili</label>
|
|
1702
|
+
<select class="form-input form-select">
|
|
1703
|
+
<option value="tr">Türkçe</option>
|
|
1704
|
+
<option value="en">English</option>
|
|
1705
|
+
</select>
|
|
1706
|
+
</div>
|
|
1707
|
+
<div class="form-group">
|
|
1708
|
+
<label class="form-label">Varsayılan Para Birimi</label>
|
|
1709
|
+
<select class="form-input form-select">
|
|
1710
|
+
<option value="TRY">₺ Türk Lirası</option>
|
|
1711
|
+
<option value="USD">$ Dolar</option>
|
|
1712
|
+
<option value="EUR">€ Euro</option>
|
|
1713
|
+
</select>
|
|
1714
|
+
</div>
|
|
1715
|
+
<div class="form-group">
|
|
1716
|
+
<label class="form-label">Zaman Dilimi</label>
|
|
1717
|
+
<select class="form-input form-select">
|
|
1718
|
+
<option value="Europe/Istanbul">Europe/Istanbul (UTC+3)</option>
|
|
1719
|
+
</select>
|
|
1720
|
+
</div>
|
|
1721
|
+
<button class="btn-primary" onclick="saveSettings()">Kaydet</button>
|
|
1722
|
+
</div>
|
|
1723
|
+
<div id="settings-account" class="settings-tab" style="display: none;">
|
|
1724
|
+
<h3 style="margin-bottom: 20px;">Hesap Ayarları</h3>
|
|
1725
|
+
<div class="form-group">
|
|
1726
|
+
<label class="form-label">Firma Adı</label>
|
|
1727
|
+
<input type="text" class="form-input" id="company-name" placeholder="Firma adınızı girin">
|
|
1728
|
+
</div>
|
|
1729
|
+
<div class="form-group">
|
|
1730
|
+
<label class="form-label">E-posta</label>
|
|
1731
|
+
<input type="email" class="form-input" id="user-email" placeholder="E-posta adresiniz">
|
|
1732
|
+
</div>
|
|
1733
|
+
<div class="form-group">
|
|
1734
|
+
<label class="form-label">Lisans Anahtarı</label>
|
|
1735
|
+
<input type="text" class="form-input" id="license-key" placeholder="XXXX-XXXX-XXXX-XXXX">
|
|
1736
|
+
</div>
|
|
1737
|
+
<button class="btn-primary" onclick="saveSettings()">Kaydet</button>
|
|
1738
|
+
</div>
|
|
1739
|
+
<div id="settings-ai" class="settings-tab" style="display: none;">
|
|
1740
|
+
<h3 style="margin-bottom: 20px;">AI Model Ayarları</h3>
|
|
1741
|
+
<div class="form-group">
|
|
1742
|
+
<label class="form-label">AI Sağlayıcı</label>
|
|
1743
|
+
<select class="form-input form-select">
|
|
1744
|
+
<option value="OpenAI">OpenAI (GPT-4)</option>
|
|
1745
|
+
<option value="Anthropic">Anthropic (Claude)</option>
|
|
1746
|
+
<option value="Gemini">Google Gemini</option>
|
|
1747
|
+
</select>
|
|
1748
|
+
</div>
|
|
1749
|
+
<div class="form-group">
|
|
1750
|
+
<label class="form-label">API Key</label>
|
|
1751
|
+
<input type="password" class="form-input" id="api-key" placeholder="API anahtarınızı girin">
|
|
1752
|
+
</div>
|
|
1753
|
+
<div class="form-group">
|
|
1754
|
+
<label class="form-label">Model</label>
|
|
1755
|
+
<select class="form-input form-select">
|
|
1756
|
+
<option value="gpt-4">GPT-4</option>
|
|
1757
|
+
<option value="gpt-4o">GPT-4o</option>
|
|
1758
|
+
<option value="gpt-3.5">GPT-3.5 Turbo</option>
|
|
1759
|
+
</select>
|
|
1760
|
+
</div>
|
|
1761
|
+
<button class="btn-primary" onclick="saveSettings()">Kaydet</button>
|
|
1762
|
+
</div>
|
|
1763
|
+
<div id="settings-notifications" class="settings-tab" style="display: none;">
|
|
1764
|
+
<h3 style="margin-bottom: 20px;">Bildirim Ayarları</h3>
|
|
1765
|
+
<div class="form-group">
|
|
1766
|
+
<label style="display: flex; align-items: center; gap: 10px; cursor: pointer;">
|
|
1767
|
+
<input type="checkbox" checked> Yeni sipariş bildirimleri
|
|
1768
|
+
</label>
|
|
1769
|
+
</div>
|
|
1770
|
+
<div class="form-group">
|
|
1771
|
+
<label style="display: flex; align-items: center; gap: 10px; cursor: pointer;">
|
|
1772
|
+
<input type="checkbox" checked> Stok uyarıları
|
|
1773
|
+
</label>
|
|
1774
|
+
</div>
|
|
1775
|
+
<div class="form-group">
|
|
1776
|
+
<label style="display: flex; align-items: center; gap: 10px; cursor: pointer;">
|
|
1777
|
+
<input type="checkbox"> AI özet bildirimleri
|
|
1778
|
+
</label>
|
|
1779
|
+
</div>
|
|
1780
|
+
<button class="btn-primary" onclick="saveSettings()">Kaydet</button>
|
|
1781
|
+
</div>
|
|
1782
|
+
</div>
|
|
1783
|
+
</div>
|
|
1784
|
+
</div>
|
|
1785
|
+
|
|
1786
|
+
<!-- Help Page -->
|
|
1787
|
+
<div class="page" id="page-help">
|
|
1788
|
+
<div class="page-header">
|
|
1789
|
+
<div>
|
|
1790
|
+
<div class="page-title">❓ Yardım</div>
|
|
1791
|
+
<div class="page-subtitle">Sık sorulan sorular ve destek</div>
|
|
1792
|
+
</div>
|
|
1793
|
+
</div>
|
|
1794
|
+
|
|
1795
|
+
<div class="help-section">
|
|
1796
|
+
<div class="help-title">📦 Sipariş Yönetimi</div>
|
|
1797
|
+
<div class="help-item" onclick="toggleHelp(this)">
|
|
1798
|
+
<div class="help-question">Siparişlerimi nasıl yönetebilirim?</div>
|
|
1799
|
+
<div class="help-answer">Siparişler sayfasından tüm siparişlerinizi görüntüleyebilir, durumlarını güncelleyebilir ve detaylarına bakabilirsiniz.</div>
|
|
1800
|
+
</div>
|
|
1801
|
+
<div class="help-item" onclick="toggleHelp(this)">
|
|
1802
|
+
<div class="help-question">Toplu sipariş işlemi yapabilir miyim?</div>
|
|
1803
|
+
<div class="help-answer">Evet, siparişler sayfasında birden fazla sipariş seçerek toplu işlem yapabilirsiniz.</div>
|
|
1804
|
+
</div>
|
|
1805
|
+
</div>
|
|
1806
|
+
|
|
1807
|
+
<div class="help-section">
|
|
1808
|
+
<div class="help-title">🛍️ Ürün & Stok</div>
|
|
1809
|
+
<div class="help-item" onclick="toggleHelp(this)">
|
|
1810
|
+
<div class="help-question">Yeni ürün nasıl eklerim?</div>
|
|
1811
|
+
<div class="help-answer">Ürünler sayfasından "Yeni Ürün Ekle" butonuna tıklayarak ürün bilgilerini girebilirsiniz.</div>
|
|
1812
|
+
</div>
|
|
1813
|
+
<div class="help-item" onclick="toggleHelp(this)">
|
|
1814
|
+
<div class="help-question">Stok senkronizasyonu nasıl çalışır?</div>
|
|
1815
|
+
<div class="help-answer">Mağazalar sayfasından senkronizasyon ayarlarını yapabilir ve otomatik stok güncellemesi aktifleştirebilirsiniz.</div>
|
|
1816
|
+
</div>
|
|
1817
|
+
</div>
|
|
1818
|
+
|
|
1819
|
+
<div class="help-section">
|
|
1820
|
+
<div class="help-title">💬 AI Asistan</div>
|
|
1821
|
+
<div class="help-item" onclick="toggleHelp(this)">
|
|
1822
|
+
<div class="help-question">Vantuz AI ile neler yapabilirim?</div>
|
|
1823
|
+
<div class="help-answer">AI asistanımız sipariş analizi, fiyatlandırma önerileri, rakip takibi ve daha birçok konuda size yardımcı olabilir.</div>
|
|
1824
|
+
</div>
|
|
1825
|
+
<div class="help-item" onclick="toggleHelp(this)">
|
|
1826
|
+
<div class="help-question">AI model ayarlarını nereden değiştiririm?</div>
|
|
1827
|
+
<div class="help-answer">Ayarlar > AI Ayarları bölümünden AI sağlayıcınızı ve API anahtarınızı yapılandırabilirsiniz.</div>
|
|
1828
|
+
</div>
|
|
1829
|
+
</div>
|
|
1830
|
+
|
|
1831
|
+
<div class="help-section">
|
|
1832
|
+
<div class="help-title">📞 Destek</div>
|
|
1833
|
+
<div class="help-item" onclick="toggleHelp(this)">
|
|
1834
|
+
<div class="help-question">Destek ile nasıl iletişime geçebilirim?</div>
|
|
1835
|
+
<div class="help-answer">E-posta: support@vantuz.io veya canlı destek widget'ını kullanabilirsiniz.</div>
|
|
1836
|
+
</div>
|
|
1837
|
+
</div>
|
|
1838
|
+
</div>
|
|
1839
|
+
</div>
|
|
1840
|
+
</div>
|
|
1841
|
+
|
|
1842
|
+
<!-- Toast Container -->
|
|
1843
|
+
<div class="toast-container" id="toast-container"></div>
|
|
1844
|
+
|
|
1845
|
+
<!-- Add Store Modal -->
|
|
1846
|
+
<div class="modal-overlay" id="add-store-modal">
|
|
1847
|
+
<div class="modal">
|
|
1848
|
+
<div class="modal-header">
|
|
1849
|
+
<div class="modal-title">🏪 Mağaza Ekle</div>
|
|
1850
|
+
<button class="modal-close" onclick="closeAddStoreModal()">×</button>
|
|
1851
|
+
</div>
|
|
1852
|
+
<div class="modal-body">
|
|
1853
|
+
<div class="form-group">
|
|
1854
|
+
<label class="form-label">Mağaza Adı</label>
|
|
1855
|
+
<input type="text" class="form-input" id="store-name" placeholder="Örn: Ana Mağazam">
|
|
1856
|
+
</div>
|
|
1857
|
+
<div class="form-group">
|
|
1858
|
+
<label class="form-label">Platform Seçin</label>
|
|
1859
|
+
<div class="platform-grid" id="platform-grid">
|
|
1860
|
+
<div class="platform-option" onclick="selectPlatform('trendyol', this)">
|
|
1861
|
+
<div class="platform-option-icon">🟧</div>
|
|
1862
|
+
<div class="platform-option-name">Trendyol</div>
|
|
1863
|
+
</div>
|
|
1864
|
+
<div class="platform-option" onclick="selectPlatform('hepsiburada', this)">
|
|
1865
|
+
<div class="platform-option-icon">🟧</div>
|
|
1866
|
+
<div class="platform-option-name">Hepsiburada</div>
|
|
1867
|
+
</div>
|
|
1868
|
+
<div class="platform-option" onclick="selectPlatform('amazon', this)">
|
|
1869
|
+
<div class="platform-option-icon">📦</div>
|
|
1870
|
+
<div class="platform-option-name">Amazon</div>
|
|
1871
|
+
</div>
|
|
1872
|
+
<div class="platform-option" onclick="selectPlatform('n11', this)">
|
|
1873
|
+
<div class="platform-option-icon">🐞</div>
|
|
1874
|
+
<div class="platform-option-name">n11</div>
|
|
1875
|
+
</div>
|
|
1876
|
+
<div class="platform-option" onclick="selectPlatform('shopify', this)">
|
|
1877
|
+
<div class="platform-option-icon">🛍️</div>
|
|
1878
|
+
<div class="platform-option-name">Shopify</div>
|
|
1879
|
+
</div>
|
|
1880
|
+
<div class="platform-option" onclick="selectPlatform('woocommerce', this)">
|
|
1881
|
+
<div class="platform-option-icon">🔧</div>
|
|
1882
|
+
<div class="platform-option-name">WooCommerce</div>
|
|
1883
|
+
</div>
|
|
1884
|
+
</div>
|
|
1885
|
+
</div>
|
|
1886
|
+
<div id="credentials-section" style="display: none;">
|
|
1887
|
+
<div class="form-group">
|
|
1888
|
+
<label class="form-label" id="api-key-label">API Key</label>
|
|
1889
|
+
<input type="password" class="form-input" id="store-api-key" placeholder="API anahtarınız">
|
|
1890
|
+
</div>
|
|
1891
|
+
<div class="form-group" id="api-secret-group">
|
|
1892
|
+
<label class="form-label">API Secret</label>
|
|
1893
|
+
<input type="password" class="form-input" id="store-api-secret" placeholder="API secret">
|
|
1894
|
+
</div>
|
|
1895
|
+
</div>
|
|
1896
|
+
</div>
|
|
1897
|
+
<div class="modal-footer">
|
|
1898
|
+
<button class="btn-secondary" onclick="closeAddStoreModal()">İptal</button>
|
|
1899
|
+
<button class="btn-secondary" onclick="testConnection()">🔗 Test Et</button>
|
|
1900
|
+
<button class="btn-primary" onclick="addStore()">➕ Ekle</button>
|
|
1901
|
+
</div>
|
|
1902
|
+
</div>
|
|
1903
|
+
</div>
|
|
1904
|
+
|
|
1905
|
+
<!-- Edit Store Modal -->
|
|
1906
|
+
<div class="modal-overlay" id="edit-store-modal">
|
|
1907
|
+
<div class="modal">
|
|
1908
|
+
<div class="modal-header">
|
|
1909
|
+
<div class="modal-title">✏️ Mağaza Düzenle</div>
|
|
1910
|
+
<button class="modal-close" onclick="closeEditStoreModal()">×</button>
|
|
1911
|
+
</div>
|
|
1912
|
+
<div class="modal-body">
|
|
1913
|
+
<input type="hidden" id="edit-store-id">
|
|
1914
|
+
<div class="form-group">
|
|
1915
|
+
<label class="form-label">Mağaza Adı</label>
|
|
1916
|
+
<input type="text" class="form-input" id="edit-store-name" placeholder="Mağaza adı">
|
|
1917
|
+
</div>
|
|
1918
|
+
<div class="form-group">
|
|
1919
|
+
<label class="form-label">Platform</label>
|
|
1920
|
+
<select class="form-input form-select" id="edit-store-platform">
|
|
1921
|
+
<option value="trendyol">Trendyol</option>
|
|
1922
|
+
<option value="hepsiburada">Hepsiburada</option>
|
|
1923
|
+
<option value="amazon">Amazon</option>
|
|
1924
|
+
<option value="n11">n11</option>
|
|
1925
|
+
<option value="shopify">Shopify</option>
|
|
1926
|
+
<option value="woocommerce">WooCommerce</option>
|
|
1927
|
+
</select>
|
|
1928
|
+
</div>
|
|
1929
|
+
<div class="form-group">
|
|
1930
|
+
<label class="form-label">Durum</label>
|
|
1931
|
+
<div style="display: flex; align-items: center; gap: 10px;">
|
|
1932
|
+
<label class="toggle-switch">
|
|
1933
|
+
<input type="checkbox" id="edit-store-active" checked>
|
|
1934
|
+
<span class="toggle-slider"></span>
|
|
1935
|
+
</label>
|
|
1936
|
+
<span id="edit-store-status-text">Aktif</span>
|
|
1937
|
+
</div>
|
|
1938
|
+
</div>
|
|
1939
|
+
</div>
|
|
1940
|
+
<div class="modal-footer">
|
|
1941
|
+
<button class="btn-secondary" onclick="closeEditStoreModal()">İptal</button>
|
|
1942
|
+
<button class="btn-primary" onclick="updateStore()">💾 Kaydet</button>
|
|
1943
|
+
</div>
|
|
1944
|
+
</div>
|
|
1945
|
+
</div>
|
|
1946
|
+
|
|
1947
|
+
<!-- Delete Dialog -->
|
|
1948
|
+
<div class="dialog-overlay" id="delete-dialog">
|
|
1949
|
+
<div class="dialog">
|
|
1950
|
+
<div class="dialog-icon">🗑️</div>
|
|
1951
|
+
<div class="dialog-title">Mağazayı Sil</div>
|
|
1952
|
+
<div class="dialog-message">Bu mağazayı silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.</div>
|
|
1953
|
+
<input type="hidden" id="delete-store-id">
|
|
1954
|
+
<div class="dialog-buttons">
|
|
1955
|
+
<button class="btn-secondary" onclick="closeDeleteDialog()">İptal</button>
|
|
1956
|
+
<button class="btn-primary" style="background: var(--error);" onclick="confirmDelete()">🗑️ Sil</button>
|
|
1957
|
+
</div>
|
|
1958
|
+
</div>
|
|
1959
|
+
</div>
|
|
1960
|
+
|
|
1961
|
+
<script>
|
|
1962
|
+
// API Base URL
|
|
1963
|
+
let API_BASE = '';
|
|
1964
|
+
|
|
1965
|
+
async function init() {
|
|
1966
|
+
try {
|
|
1967
|
+
if (window.vantuz && window.vantuz.apiBase) {
|
|
1968
|
+
API_BASE = await window.vantuz.apiBase();
|
|
1969
|
+
} else {
|
|
1970
|
+
API_BASE = 'http://localhost:3131';
|
|
1971
|
+
}
|
|
1972
|
+
await loadSettings();
|
|
1973
|
+
await refreshDashboard();
|
|
1974
|
+
} catch (e) {
|
|
1975
|
+
console.error('Init error:', e);
|
|
1976
|
+
showError('Bağlantı hatası. Lütfen uygulamayı yeniden başlatın.');
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
// Navigation
|
|
1981
|
+
function showPage(page) {
|
|
1982
|
+
document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
|
|
1983
|
+
document.querySelectorAll('.nav-item').forEach(item => item.classList.remove('active'));
|
|
1984
|
+
|
|
1985
|
+
const pageEl = document.getElementById('page-' + page);
|
|
1986
|
+
if (pageEl) {
|
|
1987
|
+
pageEl.classList.add('active');
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
// Update nav active state
|
|
1991
|
+
const navItems = document.querySelectorAll('.nav-item');
|
|
1992
|
+
if (page === 'dashboard') navItems[0].classList.add('active');
|
|
1993
|
+
if (page === 'orders') navItems[1].classList.add('active');
|
|
1994
|
+
if (page === 'products') navItems[2].classList.add('active');
|
|
1995
|
+
if (page === 'stores') navItems[3].classList.add('active');
|
|
1996
|
+
if (page === 'chat') navItems[4].classList.add('active');
|
|
1997
|
+
if (page === 'analytics') navItems[5].classList.add('active');
|
|
1998
|
+
if (page === 'settings') navItems[6].classList.add('active');
|
|
1999
|
+
if (page === 'help') navItems[7].classList.add('active');
|
|
2000
|
+
|
|
2001
|
+
// Load data for page
|
|
2002
|
+
if (page === 'orders') refreshOrders();
|
|
2003
|
+
if (page === 'products') refreshProducts();
|
|
2004
|
+
if (page === 'stores') refreshStores();
|
|
2005
|
+
if (page === 'analytics') refreshAnalytics();
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
// Settings tabs
|
|
2009
|
+
function showSettingsTab(tab) {
|
|
2010
|
+
document.querySelectorAll('.settings-tab').forEach(t => t.style.display = 'none');
|
|
2011
|
+
document.querySelectorAll('.settings-nav-item').forEach(n => n.classList.remove('active'));
|
|
2012
|
+
|
|
2013
|
+
document.getElementById('settings-' + tab).style.display = 'block';
|
|
2014
|
+
event.target.classList.add('active');
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
// Toggle help item
|
|
2018
|
+
function toggleHelp(el) {
|
|
2019
|
+
el.classList.toggle('expanded');
|
|
2020
|
+
}
|
|
2021
|
+
|
|
2022
|
+
// API helper
|
|
2023
|
+
async function apiGet(endpoint) {
|
|
2024
|
+
if (!API_BASE) API_BASE = 'http://localhost:3131';
|
|
2025
|
+
const response = await fetch(`${API_BASE}${endpoint}`);
|
|
2026
|
+
if (!response.ok) throw new Error('API Error');
|
|
2027
|
+
return response.json();
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
async function apiPost(endpoint, data) {
|
|
2031
|
+
if (!API_BASE) API_BASE = 'http://localhost:3131';
|
|
2032
|
+
const response = await fetch(`${API_BASE}${endpoint}`, {
|
|
2033
|
+
method: 'POST',
|
|
2034
|
+
headers: { 'Content-Type': 'application/json' },
|
|
2035
|
+
body: JSON.stringify(data)
|
|
2036
|
+
});
|
|
2037
|
+
if (!response.ok) throw new Error('API Error');
|
|
2038
|
+
return response.json();
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
// Load settings
|
|
2042
|
+
async function loadSettings() {
|
|
2043
|
+
try {
|
|
2044
|
+
const settings = await apiGet('/api/settings');
|
|
2045
|
+
if (settings.user) {
|
|
2046
|
+
const userInfo = document.getElementById('user-info');
|
|
2047
|
+
userInfo.innerHTML = `
|
|
2048
|
+
<div class="user-avatar">${settings.user.avatar || 'V'}</div>
|
|
2049
|
+
<div>
|
|
2050
|
+
<div class="user-name">${settings.user.name}</div>
|
|
2051
|
+
<div class="user-plan">${settings.user.plan}</div>
|
|
2052
|
+
</div>
|
|
2053
|
+
`;
|
|
2054
|
+
}
|
|
2055
|
+
if (settings.companyInfo) {
|
|
2056
|
+
document.getElementById('company-name').value = settings.companyInfo.companyName || '';
|
|
2057
|
+
}
|
|
2058
|
+
} catch (e) {
|
|
2059
|
+
console.error('Settings load error:', e);
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
// Dashboard
|
|
2064
|
+
async function refreshDashboard() {
|
|
2065
|
+
try {
|
|
2066
|
+
const [stats, orders, settings] = await Promise.all([
|
|
2067
|
+
apiGet('/api/stats'),
|
|
2068
|
+
apiGet('/api/orders'),
|
|
2069
|
+
apiGet('/api/settings')
|
|
2070
|
+
]);
|
|
2071
|
+
|
|
2072
|
+
// Update stats
|
|
2073
|
+
const statsGrid = document.getElementById('stats-grid');
|
|
2074
|
+
statsGrid.innerHTML = `
|
|
2075
|
+
<div class="stat-card">
|
|
2076
|
+
<div class="stat-icon orders">📦</div>
|
|
2077
|
+
<div class="stat-value">${stats.orders || 0}</div>
|
|
2078
|
+
<div class="stat-label">Toplam Sipariş</div>
|
|
2079
|
+
<div class="stat-change positive">↑ 12% bu hafta</div>
|
|
2080
|
+
</div>
|
|
2081
|
+
<div class="stat-card">
|
|
2082
|
+
<div class="stat-icon revenue">💰</div>
|
|
2083
|
+
<div class="stat-value">₺${formatNumber(stats.revenue || 0)}</div>
|
|
2084
|
+
<div class="stat-label">Bu Ay Ciro</div>
|
|
2085
|
+
<div class="stat-change positive">↑ 8% bu hafta</div>
|
|
2086
|
+
</div>
|
|
2087
|
+
<div class="stat-card">
|
|
2088
|
+
<div class="stat-icon products">🛍️</div>
|
|
2089
|
+
<div class="stat-value">${formatNumber(stats.products || 0)}</div>
|
|
2090
|
+
<div class="stat-label">Aktif Ürün</div>
|
|
2091
|
+
<div class="stat-change positive">↑ 23 yeni</div>
|
|
2092
|
+
</div>
|
|
2093
|
+
<div class="stat-card">
|
|
2094
|
+
<div class="stat-icon stores">🏪</div>
|
|
2095
|
+
<div class="stat-value">${stats.stores || 0}</div>
|
|
2096
|
+
<div class="stat-label">Aktif Mağaza</div>
|
|
2097
|
+
<div class="stat-change">Hepsi aktif</div>
|
|
2098
|
+
</div>
|
|
2099
|
+
`;
|
|
2100
|
+
|
|
2101
|
+
// Update welcome message
|
|
2102
|
+
const userName = settings.user?.name || 'Kullanıcı';
|
|
2103
|
+
document.getElementById('dashboard-title').textContent = `Hoş Geldin, ${userName}! 👋`;
|
|
2104
|
+
document.getElementById('dashboard-subtitle').textContent = `${orders.length || 0} yeni siparişin var`;
|
|
2105
|
+
|
|
2106
|
+
// Update order badge
|
|
2107
|
+
document.getElementById('order-badge').textContent = orders.length || 0;
|
|
2108
|
+
|
|
2109
|
+
// Update recent orders
|
|
2110
|
+
const recentOrders = orders.slice(0, 5);
|
|
2111
|
+
const ordersPanel = document.getElementById('recent-orders');
|
|
2112
|
+
if (recentOrders.length === 0) {
|
|
2113
|
+
ordersPanel.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 40px;">Henüz sipariş yok</div>';
|
|
2114
|
+
} else {
|
|
2115
|
+
ordersPanel.innerHTML = recentOrders.map(order => `
|
|
2116
|
+
<div class="order-item">
|
|
2117
|
+
<div class="order-id">${order.orderNumber || '#---'}</div>
|
|
2118
|
+
<div class="order-customer">${order.customerName || 'Müşteri'}</div>
|
|
2119
|
+
<div class="order-status ${order.status || 'new'}">${getStatusText(order.status)}</div>
|
|
2120
|
+
<div class="order-total">₺${formatNumber(order.totalAmount || 0)}</div>
|
|
2121
|
+
</div>
|
|
2122
|
+
`).join('');
|
|
2123
|
+
}
|
|
2124
|
+
} catch (e) {
|
|
2125
|
+
console.error('Dashboard refresh error:', e);
|
|
2126
|
+
showError('Dashboard yüklenirken hata oluştu');
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
// Orders page
|
|
2131
|
+
async function refreshOrders() {
|
|
2132
|
+
try {
|
|
2133
|
+
const orders = await apiGet('/api/orders');
|
|
2134
|
+
const ordersList = document.getElementById('orders-list');
|
|
2135
|
+
if (orders.length === 0) {
|
|
2136
|
+
ordersList.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 40px;">Henüz sipariş yok</div>';
|
|
2137
|
+
} else {
|
|
2138
|
+
ordersList.innerHTML = `
|
|
2139
|
+
<table class="data-table">
|
|
2140
|
+
<thead>
|
|
2141
|
+
<tr>
|
|
2142
|
+
<th>Sipariş No</th>
|
|
2143
|
+
<th>Müşteri</th>
|
|
2144
|
+
<th>Tutar</th>
|
|
2145
|
+
<th>Durum</th>
|
|
2146
|
+
<th>Tarih</th>
|
|
2147
|
+
</tr>
|
|
2148
|
+
</thead>
|
|
2149
|
+
<tbody>
|
|
2150
|
+
${orders.map(order => `
|
|
2151
|
+
<tr>
|
|
2152
|
+
<td>${order.orderNumber || '#---'}</td>
|
|
2153
|
+
<td>${order.customerName || 'Müşteri'}</td>
|
|
2154
|
+
<td>₺${formatNumber(order.totalAmount || 0)}</td>
|
|
2155
|
+
<td><span class="order-status ${order.status || 'new'}">${getStatusText(order.status)}</span></td>
|
|
2156
|
+
<td>${formatDate(order.orderDate)}</td>
|
|
2157
|
+
</tr>
|
|
2158
|
+
`).join('')}
|
|
2159
|
+
</tbody>
|
|
2160
|
+
</table>
|
|
2161
|
+
`;
|
|
2162
|
+
}
|
|
2163
|
+
} catch (e) {
|
|
2164
|
+
console.error('Orders refresh error:', e);
|
|
2165
|
+
document.getElementById('orders-list').innerHTML = '<div class="error-message">Siparişler yüklenirken hata oluştu<button class="retry-btn" onclick="refreshOrders()">Tekrar Dene</button></div>';
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2169
|
+
// Products page
|
|
2170
|
+
async function refreshProducts() {
|
|
2171
|
+
try {
|
|
2172
|
+
const products = await apiGet('/api/products');
|
|
2173
|
+
const productsGrid = document.getElementById('products-grid');
|
|
2174
|
+
if (products.length === 0) {
|
|
2175
|
+
productsGrid.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 40px;">Henüz ürün yok</div>';
|
|
2176
|
+
} else {
|
|
2177
|
+
productsGrid.innerHTML = products.map(product => `
|
|
2178
|
+
<div class="card">
|
|
2179
|
+
<div class="card-header">
|
|
2180
|
+
<div>
|
|
2181
|
+
<div class="card-title">${product.name || 'Ürün'}</div>
|
|
2182
|
+
<div class="card-subtitle">${product.brand || 'Marka belirtilmemiş'}</div>
|
|
2183
|
+
</div>
|
|
2184
|
+
<span class="card-badge active">Aktif</span>
|
|
2185
|
+
</div>
|
|
2186
|
+
<div style="margin-top: 15px; font-size: 14px; color: var(--text-secondary);">
|
|
2187
|
+
${product.description ? product.description.substring(0, 100) + '...' : 'Açıklama yok'}
|
|
2188
|
+
</div>
|
|
2189
|
+
<div class="card-stats">
|
|
2190
|
+
<div class="card-stat">
|
|
2191
|
+
<div class="card-stat-value">${product.sku || '-'}</div>
|
|
2192
|
+
<div class="card-stat-label">SKU</div>
|
|
2193
|
+
</div>
|
|
2194
|
+
<div class="card-stat">
|
|
2195
|
+
<div class="card-stat-value">${product.barcode || '-'}</div>
|
|
2196
|
+
<div class="card-stat-label">Barkod</div>
|
|
2197
|
+
</div>
|
|
2198
|
+
</div>
|
|
2199
|
+
</div>
|
|
2200
|
+
`).join('');
|
|
2201
|
+
}
|
|
2202
|
+
} catch (e) {
|
|
2203
|
+
console.error('Products refresh error:', e);
|
|
2204
|
+
document.getElementById('products-grid').innerHTML = '<div class="error-message">Ürünler yüklenirken hata oluştu<button class="retry-btn" onclick="refreshProducts()">Tekrar Dene</button></div>';
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
// Stores page
|
|
2209
|
+
async function refreshStores() {
|
|
2210
|
+
try {
|
|
2211
|
+
const stores = await apiGet('/api/stores');
|
|
2212
|
+
const storesGrid = document.getElementById('stores-grid');
|
|
2213
|
+
if (stores.length === 0) {
|
|
2214
|
+
storesGrid.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 40px;">Henüz mağaza yok. Ayarlardan mağaza ekleyebilirsiniz.</div>';
|
|
2215
|
+
} else {
|
|
2216
|
+
storesGrid.innerHTML = stores.map(store => `
|
|
2217
|
+
<div class="card">
|
|
2218
|
+
<div class="card-header">
|
|
2219
|
+
<div>
|
|
2220
|
+
<div class="card-title">${store.name || 'Mağaza'}</div>
|
|
2221
|
+
<div class="card-subtitle">${store.platform || 'Platform'}</div>
|
|
2222
|
+
</div>
|
|
2223
|
+
<span class="card-badge ${store.isActive !== false ? 'active' : 'inactive'}">${store.isActive !== false ? 'Aktif' : 'Pasif'}</span>
|
|
2224
|
+
</div>
|
|
2225
|
+
<div class="card-stats">
|
|
2226
|
+
<div class="card-stat">
|
|
2227
|
+
<div class="card-stat-value">${store.credentials ? '••••' : '-'}</div>
|
|
2228
|
+
<div class="card-stat-label">Kimlik Bilgisi</div>
|
|
2229
|
+
</div>
|
|
2230
|
+
</div>
|
|
2231
|
+
</div>
|
|
2232
|
+
`).join('');
|
|
2233
|
+
}
|
|
2234
|
+
} catch (e) {
|
|
2235
|
+
console.error('Stores refresh error:', e);
|
|
2236
|
+
document.getElementById('stores-grid').innerHTML = '<div class="error-message">Mağazalar yüklenirken hata oluştu<button class="retry-btn" onclick="refreshStores()">Tekrar Dene</button></div>';
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
// Analytics
|
|
2241
|
+
async function refreshAnalytics() {
|
|
2242
|
+
try {
|
|
2243
|
+
const stats = await apiGet('/api/stats');
|
|
2244
|
+
document.getElementById('analytics-orders').textContent = stats.orders || 0;
|
|
2245
|
+
document.getElementById('analytics-revenue').textContent = '₺' + formatNumber(stats.revenue || 0);
|
|
2246
|
+
document.getElementById('analytics-products').textContent = formatNumber(stats.products || 0);
|
|
2247
|
+
document.getElementById('analytics-stores').textContent = stats.stores || 0;
|
|
2248
|
+
} catch (e) {
|
|
2249
|
+
console.error('Analytics refresh error:', e);
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
// AI Chat
|
|
2254
|
+
async function sendMessage() {
|
|
2255
|
+
const input = document.getElementById('ai-input');
|
|
2256
|
+
const message = input.value.trim();
|
|
2257
|
+
if (!message) return;
|
|
2258
|
+
|
|
2259
|
+
const messagesDiv = document.getElementById('ai-messages');
|
|
2260
|
+
messagesDiv.innerHTML += `<div class="ai-message user">${escapeHtml(message)}</div>`;
|
|
2261
|
+
input.value = '';
|
|
2262
|
+
|
|
2263
|
+
const sendBtn = document.getElementById('ai-send');
|
|
2264
|
+
sendBtn.disabled = true;
|
|
2265
|
+
|
|
2266
|
+
try {
|
|
2267
|
+
const response = await apiPost('/api/chat', { message });
|
|
2268
|
+
messagesDiv.innerHTML += `<div class="ai-message bot">${escapeHtml(response.response)}</div>`;
|
|
2269
|
+
} catch (e) {
|
|
2270
|
+
messagesDiv.innerHTML += `<div class="ai-message bot">Üzgünüm, bir hata oluştu. Lütfen tekrar deneyin.</div>`;
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
sendBtn.disabled = false;
|
|
2274
|
+
messagesDiv.scrollTop = messagesDiv.scrollHeight;
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2277
|
+
async function sendChatPageMessage() {
|
|
2278
|
+
const input = document.getElementById('chat-page-input');
|
|
2279
|
+
const message = input.value.trim();
|
|
2280
|
+
if (!message) return;
|
|
2281
|
+
|
|
2282
|
+
const messagesDiv = document.getElementById('chat-page-messages');
|
|
2283
|
+
messagesDiv.innerHTML += `<div class="ai-message user">${escapeHtml(message)}</div>`;
|
|
2284
|
+
input.value = '';
|
|
2285
|
+
|
|
2286
|
+
const sendBtn = document.getElementById('chat-page-send');
|
|
2287
|
+
sendBtn.disabled = true;
|
|
2288
|
+
|
|
2289
|
+
try {
|
|
2290
|
+
const response = await apiPost('/api/chat', { message });
|
|
2291
|
+
messagesDiv.innerHTML += `<div class="ai-message bot">${escapeHtml(response.response)}</div>`;
|
|
2292
|
+
} catch (e) {
|
|
2293
|
+
messagesDiv.innerHTML += `<div class="ai-message bot">Üzgünüm, bir hata oluştu. Lütfen tekrar deneyin.</div>`;
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2296
|
+
sendBtn.disabled = false;
|
|
2297
|
+
messagesDiv.scrollTop = messagesDiv.scrollHeight;
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
// Settings save
|
|
2301
|
+
function saveSettings() {
|
|
2302
|
+
alert('Ayarlar kaydedildi! (Demo)');
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
// Helper functions
|
|
2306
|
+
function formatNumber(num) {
|
|
2307
|
+
return new Intl.NumberFormat('tr-TR').format(num);
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
function formatDate(dateStr) {
|
|
2311
|
+
if (!dateStr) return '-';
|
|
2312
|
+
const date = new Date(dateStr);
|
|
2313
|
+
return date.toLocaleDateString('tr-TR');
|
|
2314
|
+
}
|
|
2315
|
+
|
|
2316
|
+
function getStatusText(status) {
|
|
2317
|
+
const statusMap = {
|
|
2318
|
+
'new': 'Yeni',
|
|
2319
|
+
'preparing': 'Hazırlanıyor',
|
|
2320
|
+
'shipped': 'Kargoda',
|
|
2321
|
+
'delivered': 'Teslim Edildi',
|
|
2322
|
+
'cancelled': 'İptal'
|
|
2323
|
+
};
|
|
2324
|
+
return statusMap[status] || status || 'Bilinmiyor';
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
function escapeHtml(text) {
|
|
2328
|
+
const div = document.createElement('div');
|
|
2329
|
+
div.textContent = text;
|
|
2330
|
+
return div.innerHTML;
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
function showError(message) {
|
|
2334
|
+
console.error(message);
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
// ==================== TOAST NOTIFICATION SYSTEM ====================
|
|
2338
|
+
function showToast(type, title, message, duration = 5000) {
|
|
2339
|
+
const container = document.getElementById('toast-container');
|
|
2340
|
+
const toast = document.createElement('div');
|
|
2341
|
+
toast.className = `toast ${type}`;
|
|
2342
|
+
|
|
2343
|
+
const icons = {
|
|
2344
|
+
success: '✅',
|
|
2345
|
+
error: '❌',
|
|
2346
|
+
warning: '⚠️',
|
|
2347
|
+
info: 'ℹ️'
|
|
2348
|
+
};
|
|
2349
|
+
|
|
2350
|
+
toast.innerHTML = `
|
|
2351
|
+
<div class="toast-icon">${icons[type] || icons.info}</div>
|
|
2352
|
+
<div class="toast-content">
|
|
2353
|
+
<div class="toast-title">${title}</div>
|
|
2354
|
+
<div class="toast-message">${message}</div>
|
|
2355
|
+
</div>
|
|
2356
|
+
<button class="toast-close" onclick="closeToast(this)">×</button>
|
|
2357
|
+
`;
|
|
2358
|
+
|
|
2359
|
+
container.appendChild(toast);
|
|
2360
|
+
|
|
2361
|
+
if (duration > 0) {
|
|
2362
|
+
setTimeout(() => closeToast(toast), duration);
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
return toast;
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
function closeToast(element) {
|
|
2369
|
+
element.classList.add('hiding');
|
|
2370
|
+
setTimeout(() => element.remove(), 300);
|
|
2371
|
+
}
|
|
2372
|
+
|
|
2373
|
+
// ==================== ERROR BOUNDARY ====================
|
|
2374
|
+
function createErrorBoundary(containerId, errorMessage, retryFn) {
|
|
2375
|
+
const container = document.getElementById(containerId);
|
|
2376
|
+
container.innerHTML = `
|
|
2377
|
+
<div class="error-boundary">
|
|
2378
|
+
<div class="error-boundary-icon">⚠️</div>
|
|
2379
|
+
<div class="error-boundary-title">Bir Hata Oluştu</div>
|
|
2380
|
+
<div class="error-boundary-message">${errorMessage}</div>
|
|
2381
|
+
<button class="btn-primary" onclick="${retryFn}">🔄 Tekrar Dene</button>
|
|
2382
|
+
</div>
|
|
2383
|
+
`;
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
// ==================== SKELETON LOADING ====================
|
|
2387
|
+
function showSkeleton(containerId, count = 3) {
|
|
2388
|
+
const container = document.getElementById(containerId);
|
|
2389
|
+
let html = '';
|
|
2390
|
+
for (let i = 0; i < count; i++) {
|
|
2391
|
+
html += `
|
|
2392
|
+
<div class="skeleton-card">
|
|
2393
|
+
<div class="skeleton skeleton-title"></div>
|
|
2394
|
+
<div class="skeleton skeleton-text"></div>
|
|
2395
|
+
<div class="skeleton skeleton-text" style="width: 60%;"></div>
|
|
2396
|
+
</div>
|
|
2397
|
+
`;
|
|
2398
|
+
}
|
|
2399
|
+
container.innerHTML = html;
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
// ==================== STORE MANAGEMENT ====================
|
|
2403
|
+
let selectedPlatform = null;
|
|
2404
|
+
const platformCredentials = {
|
|
2405
|
+
trendyol: { key: 'Supplier ID', secret: 'API Secret' },
|
|
2406
|
+
hepsiburada: { key: 'Merchant ID', secret: 'Password' },
|
|
2407
|
+
amazon: { key: 'Seller ID', secret: 'Client Secret' },
|
|
2408
|
+
n11: { key: 'API Key', secret: 'API Secret' },
|
|
2409
|
+
shopify: { key: 'Store URL', secret: 'Access Token' },
|
|
2410
|
+
woocommerce: { key: 'Consumer Key', secret: 'Consumer Secret' }
|
|
2411
|
+
};
|
|
2412
|
+
|
|
2413
|
+
function openAddStoreModal() {
|
|
2414
|
+
document.getElementById('add-store-modal').classList.add('active');
|
|
2415
|
+
document.getElementById('store-name').value = '';
|
|
2416
|
+
document.getElementById('store-api-key').value = '';
|
|
2417
|
+
document.getElementById('store-api-secret').value = '';
|
|
2418
|
+
document.getElementById('credentials-section').style.display = 'none';
|
|
2419
|
+
document.querySelectorAll('.platform-option').forEach(el => el.classList.remove('selected'));
|
|
2420
|
+
selectedPlatform = null;
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
function closeAddStoreModal() {
|
|
2424
|
+
document.getElementById('add-store-modal').classList.remove('active');
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
function selectPlatform(platform, element) {
|
|
2428
|
+
selectedPlatform = platform;
|
|
2429
|
+
document.querySelectorAll('.platform-option').forEach(el => el.classList.remove('selected'));
|
|
2430
|
+
element.classList.add('selected');
|
|
2431
|
+
|
|
2432
|
+
// Show credentials section
|
|
2433
|
+
document.getElementById('credentials-section').style.display = 'block';
|
|
2434
|
+
const creds = platformCredentials[platform];
|
|
2435
|
+
document.getElementById('api-key-label').textContent = creds.key;
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
async function testConnection() {
|
|
2439
|
+
if (!selectedPlatform) {
|
|
2440
|
+
showToast('warning', 'Platform Seçin', 'Lütfen bir platform seçin');
|
|
2441
|
+
return;
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2444
|
+
const apiKey = document.getElementById('store-api-key').value;
|
|
2445
|
+
const apiSecret = document.getElementById('store-api-secret').value;
|
|
2446
|
+
|
|
2447
|
+
if (!apiKey) {
|
|
2448
|
+
showToast('warning', 'Bilgi Gerekli', 'API anahtarı giriniz');
|
|
2449
|
+
return;
|
|
2450
|
+
}
|
|
2451
|
+
|
|
2452
|
+
showToast('info', 'Bağlantı Testi', 'Bağlantı kontrol ediliyor...', 0);
|
|
2453
|
+
|
|
2454
|
+
try {
|
|
2455
|
+
const response = await apiPost('/api/stores/test-connection', {
|
|
2456
|
+
platform: selectedPlatform,
|
|
2457
|
+
apiKey,
|
|
2458
|
+
apiSecret
|
|
2459
|
+
});
|
|
2460
|
+
showToast('success', 'Başarılı', response.message || 'Bağlantı başarılı!');
|
|
2461
|
+
} catch (e) {
|
|
2462
|
+
showToast('error', 'Hata', 'Bağlantı başarısız: ' + (e.message || 'Bilinmeyen hata'));
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
|
|
2466
|
+
async function addStore() {
|
|
2467
|
+
const name = document.getElementById('store-name').value.trim();
|
|
2468
|
+
|
|
2469
|
+
if (!name) {
|
|
2470
|
+
showToast('warning', 'Bilgi Gerekli', 'Mağaza adı giriniz');
|
|
2471
|
+
return;
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
if (!selectedPlatform) {
|
|
2475
|
+
showToast('warning', 'Platform Seçin', 'Lütfen bir platform seçin');
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
const credentials = {};
|
|
2480
|
+
const creds = platformCredentials[selectedPlatform];
|
|
2481
|
+
const apiKey = document.getElementById('store-api-key').value;
|
|
2482
|
+
if (apiKey) credentials[creds.key.toLowerCase().replace(/ /g, '_')] = apiKey;
|
|
2483
|
+
|
|
2484
|
+
const apiSecret = document.getElementById('store-api-secret').value;
|
|
2485
|
+
if (apiSecret) credentials[creds.secret.toLowerCase().replace(/ /g, '_')] = apiSecret;
|
|
2486
|
+
|
|
2487
|
+
showToast('info', 'Mağaza Ekleniyor', 'Lütfen bekleyin...', 0);
|
|
2488
|
+
|
|
2489
|
+
try {
|
|
2490
|
+
const response = await apiPost('/api/stores', {
|
|
2491
|
+
name,
|
|
2492
|
+
platform: selectedPlatform,
|
|
2493
|
+
credentials
|
|
2494
|
+
});
|
|
2495
|
+
|
|
2496
|
+
showToast('success', 'Mağaza Eklendi', `${name} başarıyla eklendi`);
|
|
2497
|
+
closeAddStoreModal();
|
|
2498
|
+
await refreshStores();
|
|
2499
|
+
} catch (e) {
|
|
2500
|
+
showToast('error', 'Hata', 'Mağaza eklenirken hata oluştu: ' + (e.message || 'Bilinmeyen hata'));
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
|
|
2504
|
+
function openEditStoreModal(store) {
|
|
2505
|
+
document.getElementById('edit-store-id').value = store.id;
|
|
2506
|
+
document.getElementById('edit-store-name').value = store.name;
|
|
2507
|
+
document.getElementById('edit-store-platform').value = store.platform;
|
|
2508
|
+
document.getElementById('edit-store-active').checked = store.isActive !== false;
|
|
2509
|
+
document.getElementById('edit-store-status-text').textContent = store.isActive !== false ? 'Aktif' : 'Pasif';
|
|
2510
|
+
document.getElementById('edit-store-modal').classList.add('active');
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
function closeEditStoreModal() {
|
|
2514
|
+
document.getElementById('edit-store-modal').classList.remove('active');
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
async function updateStore() {
|
|
2518
|
+
const id = document.getElementById('edit-store-id').value;
|
|
2519
|
+
const name = document.getElementById('edit-store-name').value.trim();
|
|
2520
|
+
const platform = document.getElementById('edit-store-platform').value;
|
|
2521
|
+
const isActive = document.getElementById('edit-store-active').checked;
|
|
2522
|
+
|
|
2523
|
+
if (!name) {
|
|
2524
|
+
showToast('warning', 'Bilgi Gerekli', 'Mağaza adı giriniz');
|
|
2525
|
+
return;
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
showToast('info', 'Mağaza Güncelleniyor', 'Lütfen bekleyin...', 0);
|
|
2529
|
+
|
|
2530
|
+
try {
|
|
2531
|
+
await apiPost(`/api/stores/${id}`, { name, platform, isActive });
|
|
2532
|
+
showToast('success', 'Mağaza Güncellendi', 'Değişiklikler kaydedildi');
|
|
2533
|
+
closeEditStoreModal();
|
|
2534
|
+
await refreshStores();
|
|
2535
|
+
} catch (e) {
|
|
2536
|
+
showToast('error', 'Hata', 'Mağaza güncellenirken hata oluştu: ' + (e.message || 'Bilinmeyen hata'));
|
|
2537
|
+
}
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
function openDeleteDialog(storeId) {
|
|
2541
|
+
document.getElementById('delete-store-id').value = storeId;
|
|
2542
|
+
document.getElementById('delete-dialog').classList.add('active');
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
function closeDeleteDialog() {
|
|
2546
|
+
document.getElementById('delete-dialog').classList.remove('active');
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
async function confirmDelete() {
|
|
2550
|
+
const id = document.getElementById('delete-store-id').value;
|
|
2551
|
+
showToast('info', 'Mağaza Siliniyor', 'Lütfen bekleyin...', 0);
|
|
2552
|
+
|
|
2553
|
+
try {
|
|
2554
|
+
await apiDelete(`/api/stores/${id}`);
|
|
2555
|
+
showToast('success', 'Mağaza Silindi', 'Mağaza başarıyla silindi');
|
|
2556
|
+
closeDeleteDialog();
|
|
2557
|
+
await refreshStores();
|
|
2558
|
+
} catch (e) {
|
|
2559
|
+
showToast('error', 'Hata', 'Mağaza silinirken hata oluştu: ' + (e.message || 'Bilinmeyen hata'));
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2563
|
+
async function toggleStoreStatus(storeId, currentStatus) {
|
|
2564
|
+
try {
|
|
2565
|
+
await apiPost(`/api/stores/${storeId}`, { isActive: !currentStatus });
|
|
2566
|
+
await refreshStores();
|
|
2567
|
+
} catch (e) {
|
|
2568
|
+
showToast('error', 'Hata', 'Durum değiştirilemedi');
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
// ==================== ENHANCED STORES PAGE ====================
|
|
2573
|
+
async function refreshStores() {
|
|
2574
|
+
showSkeleton('stores-grid', 2);
|
|
2575
|
+
|
|
2576
|
+
try {
|
|
2577
|
+
const stores = await apiGet('/api/stores');
|
|
2578
|
+
const storesGrid = document.getElementById('stores-grid');
|
|
2579
|
+
const totalStores = stores.length;
|
|
2580
|
+
const activeStores = stores.filter(s => s.isActive !== false).length;
|
|
2581
|
+
const inactiveStores = totalStores - activeStores;
|
|
2582
|
+
|
|
2583
|
+
// Update stats
|
|
2584
|
+
document.getElementById('total-stores').textContent = totalStores;
|
|
2585
|
+
document.getElementById('active-stores').textContent = activeStores;
|
|
2586
|
+
document.getElementById('inactive-stores').textContent = inactiveStores;
|
|
2587
|
+
|
|
2588
|
+
const platformIcons = {
|
|
2589
|
+
trendyol: '🟧',
|
|
2590
|
+
hepsiburada: '🟧',
|
|
2591
|
+
amazon: '📦',
|
|
2592
|
+
n11: '🐞',
|
|
2593
|
+
shopify: '🛍️',
|
|
2594
|
+
woocommerce: '🔧'
|
|
2595
|
+
};
|
|
2596
|
+
|
|
2597
|
+
if (totalStores === 0) {
|
|
2598
|
+
storesGrid.innerHTML = `
|
|
2599
|
+
<div style="grid-column: 1/-1; text-align: center; padding: 60px 20px; color: var(--text-secondary);">
|
|
2600
|
+
<div style="font-size: 48px; margin-bottom: 15px;">🏪</div>
|
|
2601
|
+
<div style="font-size: 18px; margin-bottom: 10px;">Henüz mağaza yok</div>
|
|
2602
|
+
<div style="margin-bottom: 20px;">İlk mağazanızı ekleyerek başlayın</div>
|
|
2603
|
+
<button class="btn-primary" onclick="openAddStoreModal()">➕ Mağaza Ekle</button>
|
|
2604
|
+
</div>
|
|
2605
|
+
`;
|
|
2606
|
+
} else {
|
|
2607
|
+
storesGrid.innerHTML = stores.map(store => `
|
|
2608
|
+
<div class="store-card">
|
|
2609
|
+
<div class="store-card-header">
|
|
2610
|
+
<div class="store-platform-icon">${platformIcons[store.platform] || '🏪'}</div>
|
|
2611
|
+
<div class="store-actions">
|
|
2612
|
+
<button class="store-action-btn tooltip" onclick="openEditStoreModal(${JSON.stringify(store).replace(/"/g, '"')})" title="Düzenle">
|
|
2613
|
+
✏️
|
|
2614
|
+
<span class="tooltip-text">Düzenle</span>
|
|
2615
|
+
</button>
|
|
2616
|
+
<button class="store-action-btn tooltip" onclick="openDeleteDialog(${store.id})" title="Sil">
|
|
2617
|
+
🗑️
|
|
2618
|
+
<span class="tooltip-text">Sil</span>
|
|
2619
|
+
</button>
|
|
2620
|
+
</div>
|
|
2621
|
+
</div>
|
|
2622
|
+
<div class="card-title">${store.name}</div>
|
|
2623
|
+
<div class="card-subtitle" style="text-transform: capitalize;">${store.platform}</div>
|
|
2624
|
+
<div style="margin-top: 15px; display: flex; align-items: center; justify-content: space-between;">
|
|
2625
|
+
<span class="card-badge ${store.isActive !== false ? 'active' : 'inactive'}">
|
|
2626
|
+
${store.isActive !== false ? 'Aktif' : 'Pasif'}
|
|
2627
|
+
</span>
|
|
2628
|
+
<label class="toggle-switch tooltip">
|
|
2629
|
+
<input type="checkbox" ${store.isActive !== false ? 'checked' : ''}
|
|
2630
|
+
onchange="toggleStoreStatus(${store.id}, ${store.isActive !== false})">
|
|
2631
|
+
<span class="toggle-slider"></span>
|
|
2632
|
+
<span class="tooltip-text">${store.isActive !== false ? 'Pasif Yap' : 'Aktif Yap'}</span>
|
|
2633
|
+
</label>
|
|
2634
|
+
</div>
|
|
2635
|
+
</div>
|
|
2636
|
+
`).join('');
|
|
2637
|
+
}
|
|
2638
|
+
} catch (e) {
|
|
2639
|
+
console.error('Stores refresh error:', e);
|
|
2640
|
+
createErrorBoundary('stores-grid', 'Mağazalar yüklenirken bir hata oluştu', 'refreshStores()');
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
// ==================== ENHANCED API FUNCTIONS ====================
|
|
2645
|
+
async function apiDelete(endpoint) {
|
|
2646
|
+
if (!API_BASE) API_BASE = 'http://localhost:3131';
|
|
2647
|
+
const response = await fetch(`${API_BASE}${endpoint}`, { method: 'DELETE' });
|
|
2648
|
+
if (!response.ok) throw new Error('API Error');
|
|
2649
|
+
return response.json();
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
// ==================== ENHANCED DASHBOARD ====================
|
|
2653
|
+
async function refreshDashboard() {
|
|
2654
|
+
try {
|
|
2655
|
+
const [stats, orders, settings] = await Promise.all([
|
|
2656
|
+
apiGet('/api/stats'),
|
|
2657
|
+
apiGet('/api/orders'),
|
|
2658
|
+
apiGet('/api/settings')
|
|
2659
|
+
]);
|
|
2660
|
+
|
|
2661
|
+
// Update stats
|
|
2662
|
+
const statsGrid = document.getElementById('stats-grid');
|
|
2663
|
+
statsGrid.innerHTML = `
|
|
2664
|
+
<div class="stat-card">
|
|
2665
|
+
<div class="stat-icon orders">📦</div>
|
|
2666
|
+
<div class="stat-value">${stats.orders || 0}</div>
|
|
2667
|
+
<div class="stat-label">Toplam Sipariş</div>
|
|
2668
|
+
<div class="stat-change positive">↑ 12% bu hafta</div>
|
|
2669
|
+
</div>
|
|
2670
|
+
<div class="stat-card">
|
|
2671
|
+
<div class="stat-icon revenue">💰</div>
|
|
2672
|
+
<div class="stat-value">₺${formatNumber(stats.revenue || 0)}</div>
|
|
2673
|
+
<div class="stat-label">Bu Ay Ciro</div>
|
|
2674
|
+
<div class="stat-change positive">↑ 8% bu hafta</div>
|
|
2675
|
+
</div>
|
|
2676
|
+
<div class="stat-card">
|
|
2677
|
+
<div class="stat-icon products">🛍️</div>
|
|
2678
|
+
<div class="stat-value">${formatNumber(stats.products || 0)}</div>
|
|
2679
|
+
<div class="stat-label">Aktif Ürün</div>
|
|
2680
|
+
<div class="stat-change positive">↑ 23 yeni</div>
|
|
2681
|
+
</div>
|
|
2682
|
+
<div class="stat-card">
|
|
2683
|
+
<div class="stat-icon stores">🏪</div>
|
|
2684
|
+
<div class="stat-value">${stats.stores || 0}</div>
|
|
2685
|
+
<div class="stat-label">Aktif Mağaza</div>
|
|
2686
|
+
<div class="stat-change">Hepsi aktif</div>
|
|
2687
|
+
</div>
|
|
2688
|
+
`;
|
|
2689
|
+
|
|
2690
|
+
// Update welcome message
|
|
2691
|
+
const userName = settings.user?.name || 'Kullanıcı';
|
|
2692
|
+
document.getElementById('dashboard-title').textContent = `Hoş Geldin, ${userName}! 👋`;
|
|
2693
|
+
document.getElementById('dashboard-subtitle').textContent = `${orders.length || 0} yeni siparişin var`;
|
|
2694
|
+
|
|
2695
|
+
// Update order badge
|
|
2696
|
+
document.getElementById('order-badge').textContent = orders.length || 0;
|
|
2697
|
+
|
|
2698
|
+
// Update recent orders
|
|
2699
|
+
const recentOrders = orders.slice(0, 5);
|
|
2700
|
+
const ordersPanel = document.getElementById('recent-orders');
|
|
2701
|
+
if (recentOrders.length === 0) {
|
|
2702
|
+
ordersPanel.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 40px;">Henüz sipariş yok</div>';
|
|
2703
|
+
} else {
|
|
2704
|
+
ordersPanel.innerHTML = recentOrders.map(order => `
|
|
2705
|
+
<div class="order-item">
|
|
2706
|
+
<div class="order-id">${order.orderNumber || '#---'}</div>
|
|
2707
|
+
<div class="order-customer">${order.customerName || 'Müşteri'}</div>
|
|
2708
|
+
<div class="order-status ${order.status || 'new'}">${getStatusText(order.status)}</div>
|
|
2709
|
+
<div class="order-total">₺${formatNumber(order.totalAmount || 0)}</div>
|
|
2710
|
+
</div>
|
|
2711
|
+
`).join('');
|
|
2712
|
+
}
|
|
2713
|
+
} catch (e) {
|
|
2714
|
+
console.error('Dashboard refresh error:', e);
|
|
2715
|
+
createErrorBoundary('stats-grid', 'Dashboard yüklenirken hata oluştu', 'refreshDashboard()');
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2719
|
+
// ==================== ENHANCED ORDERS PAGE ====================
|
|
2720
|
+
async function refreshOrders() {
|
|
2721
|
+
try {
|
|
2722
|
+
const orders = await apiGet('/api/orders');
|
|
2723
|
+
const ordersList = document.getElementById('orders-list');
|
|
2724
|
+
if (orders.length === 0) {
|
|
2725
|
+
ordersList.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 40px;">Henüz sipariş yok</div>';
|
|
2726
|
+
} else {
|
|
2727
|
+
ordersList.innerHTML = `
|
|
2728
|
+
<table class="data-table">
|
|
2729
|
+
<thead>
|
|
2730
|
+
<tr>
|
|
2731
|
+
<th>Sipariş No</th>
|
|
2732
|
+
<th>Müşteri</th>
|
|
2733
|
+
<th>Tutar</th>
|
|
2734
|
+
<th>Durum</th>
|
|
2735
|
+
<th>Tarih</th>
|
|
2736
|
+
</tr>
|
|
2737
|
+
</thead>
|
|
2738
|
+
<tbody>
|
|
2739
|
+
${orders.map(order => `
|
|
2740
|
+
<tr>
|
|
2741
|
+
<td>${order.orderNumber || '#---'}</td>
|
|
2742
|
+
<td>${order.customerName || 'Müşteri'}</td>
|
|
2743
|
+
<td>₺${formatNumber(order.totalAmount || 0)}</td>
|
|
2744
|
+
<td><span class="order-status ${order.status || 'new'}">${getStatusText(order.status)}</span></td>
|
|
2745
|
+
<td>${formatDate(order.orderDate)}</td>
|
|
2746
|
+
</tr>
|
|
2747
|
+
`).join('')}
|
|
2748
|
+
</tbody>
|
|
2749
|
+
</table>
|
|
2750
|
+
`;
|
|
2751
|
+
}
|
|
2752
|
+
} catch (e) {
|
|
2753
|
+
console.error('Orders refresh error:', e);
|
|
2754
|
+
createErrorBoundary('orders-list', 'Siparişler yüklenirken hata oluştu', 'refreshOrders()');
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
// ==================== ENHANCED PRODUCTS PAGE ====================
|
|
2759
|
+
async function refreshProducts() {
|
|
2760
|
+
try {
|
|
2761
|
+
const products = await apiGet('/api/products');
|
|
2762
|
+
const productsGrid = document.getElementById('products-grid');
|
|
2763
|
+
if (products.length === 0) {
|
|
2764
|
+
productsGrid.innerHTML = '<div style="text-align: center; color: var(--text-secondary); padding: 40px;">Henüz ürün yok</div>';
|
|
2765
|
+
} else {
|
|
2766
|
+
productsGrid.innerHTML = products.map(product => `
|
|
2767
|
+
<div class="card">
|
|
2768
|
+
<div class="card-header">
|
|
2769
|
+
<div>
|
|
2770
|
+
<div class="card-title">${product.name || 'Ürün'}</div>
|
|
2771
|
+
<div class="card-subtitle">${product.brand || 'Marka belirtilmemiş'}</div>
|
|
2772
|
+
</div>
|
|
2773
|
+
<span class="card-badge active">Aktif</span>
|
|
2774
|
+
</div>
|
|
2775
|
+
<div style="margin-top: 15px; font-size: 14px; color: var(--text-secondary);">
|
|
2776
|
+
${product.description ? product.description.substring(0, 100) + '...' : 'Açıklama yok'}
|
|
2777
|
+
</div>
|
|
2778
|
+
<div class="card-stats">
|
|
2779
|
+
<div class="card-stat">
|
|
2780
|
+
<div class="card-stat-value">${product.sku || '-'}</div>
|
|
2781
|
+
<div class="card-stat-label">SKU</div>
|
|
2782
|
+
</div>
|
|
2783
|
+
<div class="card-stat">
|
|
2784
|
+
<div class="card-stat-value">${product.barcode || '-'}</div>
|
|
2785
|
+
<div class="card-stat-label">Barkod</div>
|
|
2786
|
+
</div>
|
|
2787
|
+
</div>
|
|
2788
|
+
</div>
|
|
2789
|
+
`).join('');
|
|
2790
|
+
}
|
|
2791
|
+
} catch (e) {
|
|
2792
|
+
console.error('Products refresh error:', e);
|
|
2793
|
+
createErrorBoundary('products-grid', 'Ürünler yüklenirken hata oluştu', 'refreshProducts()');
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2797
|
+
// ==================== INITIALIZATION ====================
|
|
2798
|
+
window.onload = () => {
|
|
2799
|
+
console.log('🐙 VANTUZ Desktop App loaded');
|
|
2800
|
+
init();
|
|
2801
|
+
};
|
|
2802
|
+
</script>
|
|
2803
|
+
</body>
|
|
2804
|
+
</html>
|