sikeaditya commited on
Commit
5fb06d3
·
verified ·
1 Parent(s): 795143a

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +737 -595
templates/index.html CHANGED
@@ -1,645 +1,787 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>कृषी बाजार विश्लेषण | Crop Market Analysis</title>
7
- <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
8
- <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
9
- <style>
10
- :root {
11
- --primary-color: #4CAF50;
12
- --secondary-color: #45a049;
13
- --background-color: #f9f9f9;
14
- --text-color: #333;
15
- --card-shadow: 0 2px 4px rgba(0,0,0,0.1);
16
- --border-radius: 8px;
17
- }
18
-
19
- body {
20
- background-color: var(--background-color);
21
- color: var(--text-color);
22
- font-family: 'Arial', sans-serif;
23
- line-height: 1.6;
24
- }
25
-
26
- .container {
27
- max-width: 1200px;
28
- margin: 0 auto;
29
- padding: 20px;
30
- }
31
-
32
- .header {
33
- text-align: center;
34
- margin-bottom: 30px;
35
- padding: 20px 0;
36
- }
37
-
38
- .header h1 {
39
- color: var(--primary-color);
40
- font-weight: bold;
41
- margin: 0;
42
- font-size: 2.5rem;
43
- }
44
-
45
- .language-toggle {
46
- position: fixed;
47
- top: 20px;
48
- right: 20px;
49
- z-index: 1000;
50
- }
51
-
52
- .form-section {
53
- background: white;
54
- padding: 25px;
55
- border-radius: var(--border-radius);
56
- box-shadow: var(--card-shadow);
57
- margin-bottom: 30px;
58
- }
59
-
60
- .chart-container {
61
- background: white;
62
- padding: 25px;
63
- border-radius: var(--border-radius);
64
- box-shadow: var(--card-shadow);
65
- margin-bottom: 30px;
66
- }
67
-
68
- .insights-container {
69
- background: white;
70
- padding: 25px;
71
- border-radius: var(--border-radius);
72
- box-shadow: var(--card-shadow);
73
- margin-bottom: 30px;
74
- border-left: 5px solid var(--primary-color);
75
- }
76
-
77
- .insights-container h3 {
78
- color: var(--primary-color);
79
- margin-bottom: 20px;
80
- }
81
-
82
- .loading {
83
- display: none;
84
- text-align: center;
85
- padding: 20px;
86
- background: rgba(255, 255, 255, 0.9);
87
- position: fixed;
88
- top: 50%;
89
- left: 50%;
90
- transform: translate(-50%, -50%);
91
- border-radius: var(--border-radius);
92
- box-shadow: var(--card-shadow);
93
- z-index: 1000;
94
- }
95
-
96
- .btn-custom {
97
- background-color: var(--primary-color);
98
- color: white;
99
- border: none;
100
- padding: 8px 16px;
101
- border-radius: 4px;
102
- transition: background-color 0.3s ease;
103
- }
104
-
105
- .btn-custom:hover {
106
- background-color: var(--secondary-color);
107
- color: white;
108
- }
109
-
110
- .form-control {
111
- border-radius: 4px;
112
- border: 1px solid #ddd;
113
- padding: 8px 12px;
114
- height: auto;
115
- }
116
-
117
- .form-control:focus {
118
- border-color: var(--primary-color);
119
- box-shadow: 0 0 0 0.2rem rgba(76, 175, 80, 0.25);
120
- }
121
-
122
- label {
123
- font-weight: 500;
124
- margin-bottom: 8px;
125
- color: var(--text-color);
126
- }
127
-
128
- #barChart, #lineChart, #boxChart {
129
- width: 100%;
130
- margin-bottom: 20px;
131
- }
132
-
133
- #aiInsights {
134
- line-height: 1.8;
135
- font-size: 1.1rem;
136
- }
137
-
138
- .alert {
139
- border-radius: var(--border-radius);
140
- padding: 15px 20px;
141
- margin-bottom: 20px;
142
- }
143
-
144
- .spinner-border {
145
- width: 3rem;
146
- height: 3rem;
147
- color: var(--primary-color);
148
- }
149
-
150
- #marketData {
151
- height: 100px; /* Set the height to a fixed value */
152
- overflow-y: scroll; /* Add vertical scrolling */
153
- }
154
-
155
- .insights-container {
156
- background: white;
157
- padding: 25px;
158
- border-radius: 8px;
159
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
160
- margin-bottom: 30px;
161
- }
162
-
163
- .insights-header {
164
- background: #4CAF50;
165
- color: white;
166
- padding: 15px 20px;
167
- border-radius: 8px 8px 0 0;
168
- margin: -25px -25px 20px -25px;
169
- }
170
-
171
- .insights-header h3 {
172
- margin: 0;
173
- color: white;
174
- }
175
-
176
- .insight-section {
177
- background: #f8f9fa;
178
- border-radius: 8px;
179
- padding: 20px;
180
- margin-bottom: 20px;
181
- border-left: 4px solid #4CAF50;
182
- }
183
-
184
- .insight-section h4 {
185
- color: #2E7D32;
186
- margin-bottom: 15px;
187
- font-size: 1.2rem;
188
- font-weight: bold;
189
- }
190
-
191
- .insight-card {
192
- background: white;
193
- border-radius: 6px;
194
- padding: 15px;
195
- margin-bottom: 15px;
196
- box-shadow: 0 1px 3px rgba(0,0,0,0.1);
197
- }
198
-
199
- .insight-card h5 {
200
- color: #1B5E20;
201
- margin-bottom: 10px;
202
- font-size: 1.1rem;
203
- }
204
-
205
- .insight-list {
206
- list-style: none;
207
- padding-left: 0;
208
- margin-bottom: 0;
209
- }
210
-
211
- .insight-list li {
212
- position: relative;
213
- padding-left: 20px;
214
- margin-bottom: 8px;
215
- line-height: 1.5;
216
- }
217
-
218
- .insight-list li:before {
219
- content: "•";
220
- color: #4CAF50;
221
- font-size: 1.2em;
222
- position: absolute;
223
- left: 0;
224
- top: -2px;
225
- }
226
-
227
- .price-highlight {
228
- color: #2E7D32;
229
- font-weight: bold;
230
- }
231
-
232
- .percentage-up {
233
- color: #2E7D32;
234
- font-weight: bold;
235
- }
236
-
237
- .percentage-down {
238
- color: #c62828;
239
- font-weight: bold;
240
- }
241
-
242
- .action-box {
243
- background: #E8F5E9;
244
- border-radius: 6px;
245
- padding: 15px;
246
- margin-top: 20px;
247
- border: 1px dashed #4CAF50;
248
- }
249
-
250
- .action-box h5 {
251
- color: #2E7D32;
252
- margin-bottom: 10px;
253
- font-size: 1.1rem;
254
- }
255
-
256
- .action-list {
257
- list-style: none;
258
- padding-left: 0;
259
- margin-bottom: 0;
260
- }
261
-
262
- .action-list li {
263
- position: relative;
264
- padding-left: 25px;
265
- margin-bottom: 8px;
266
- line-height: 1.5;
267
- }
268
 
269
- .action-list li:before {
270
- content: "✓";
271
- color: #4CAF50;
272
- position: absolute;
273
- left: 0;
274
- font-weight: bold;
275
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
 
277
- /* Responsive adjustments */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  @media (max-width: 768px) {
279
- .insights-container {
280
- padding: 15px;
281
- }
282
-
283
- .insights-header {
284
- padding: 12px 15px;
285
- margin: -15px -15px 15px -15px;
286
- }
287
-
288
- .insight-section {
289
- padding: 15px;
290
- }
 
 
 
 
 
 
 
291
  }
292
- @media (max-width: 768px) {
293
- .container {
294
- padding: 10px;
295
- }
296
-
297
- .header h1 {
298
- font-size: 2rem;
299
- }
300
-
301
- .form-row {
302
- flex-direction: column;
303
- }
304
-
305
- .form-group {
306
- margin-bottom: 15px;
307
- }
308
-
309
- .language-toggle {
310
- position: static;
311
- text-align: center;
312
- margin-bottom: 20px;
313
- }
314
 
315
- .btn-custom {
316
- width: 100%;
317
- }
318
-
319
- .insights-container {
320
- padding: 15px;
321
- }
322
-
323
- #aiInsights {
324
- font-size: 1rem;
325
- }
326
  }
327
- select {
328
- max-height: 200px; /* Adjust height as needed */
329
- overflow-y: auto;
330
  }
331
- </style>
332
  </head>
333
  <body>
334
- <div class="language-toggle">
335
- <button class="btn btn-custom" onclick="toggleLanguage()" id="langToggle">
336
- भाषा बदला | Change Language
337
- </button>
338
- </div>
339
-
340
- <div class="container">
341
- <div class="header">
342
- <h1 class="en">Crop Market Analysis</h1>
343
- <h1 class="mr" style="display:none;">कृषी बाजार विश्लेषण</h1>
344
- </div>
345
-
346
- <div class="form-section">
347
- <form id="filterForm">
348
- <div class="form-row">
349
- <div class="form-group col-md-3">
350
- <label for="state" class="label-state">State</label>
351
- <select class="form-control" id="state" name="state">
352
- <option value="">Select State</option>
353
- {% for state in states %}
354
- <option value="{{ state }}">{{ state }}</option>
355
- {% endfor %}
356
- </select>
357
- </div>
358
- <div class="form-group col-md-3">
359
- <label for="district" class="label-district">District</label>
360
- <select class="form-control" id="district" name="district" disabled>
361
- <option value="">Select District</option>
362
- </select>
363
- </div>
364
- <div class="form-group col-md-3">
365
- <label for="market" class="label-market">Market</label>
366
- <select class="form-control" id="market" name="market" disabled>
367
- <option value="">Select Market</option>
368
- </select>
369
- </div>
370
- <div class="form-group col-md-3">
371
- <label for="commodity" class="label-commodity">Commodity</label>
372
- <select class="form-control" id="commodity" name="commodity" disabled>
373
- <option value="">Select Commodity</option>
374
- </select>
375
- </div>
376
  </div>
377
- </form>
378
- </div>
379
-
380
- <div class="loading" id="loadingIndicator">
381
- <div class="spinner-border" role="status">
382
- <span class="sr-only">Loading...</span>
383
- </div>
384
- </div>
385
 
386
- <div class="chart-container">
387
- <div id="barChart"></div>
388
- <div id="lineChart"></div>
389
- <div id="boxChart"></div>
390
- </div>
391
-
392
- <div class="market-data-container">
393
- <div class="row">
394
- <div class="col-md-12 mb-4">
395
- <div class="card">
396
- <div class="card-header">
397
- <h4 class="en">Market Statistics</h4>
398
- <h4 class="mr" style="display:none;">बाजार आकडेवारी</h4>
399
- </div>
400
- <div class="card-body">
401
- <div class="row">
402
- <div class="col-md-3">
403
- <div class="stat-item">
404
- <h6 class="en">Total Commodities</h6>
405
- <h6 class="mr" style="display:none;">एकूण पिके</h6>
406
- <span id="totalCommodities"></span>
407
- </div>
408
- </div>
409
- <div class="col-md-3">
410
- <div class="stat-item">
411
- <h6 class="en">Average Price</h6>
412
- <h6 class="mr" style="display:none;">सरासरी किंमत</h6>
413
- <span id="avgPrice"></span>
414
- </div>
 
415
  </div>
416
- <div class="col-md-3">
417
- <div class="stat-item">
418
- <h6 class="en">Price Range</h6>
419
- <h6 class="mr" style="display:none;">किंमत श्रेणी</h6>
420
- <span id="priceRange"></span>
421
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422
  </div>
423
- <div class="col-md-3">
424
- <div class="stat-item">
425
- <h6 class="en">Total Markets</h6>
426
- <h6 class="mr" style="display:none;">एकूण बाजार</h6>
427
- <span id="totalMarkets"></span>
428
- </div>
429
- </div>
430
- </div>
431
- </div>
432
- </div>
433
  </div>
434
- </div>
435
 
436
- <div class="row">
437
- <div class="col-md-6 mb-4">
438
- <div class="card">
439
- <div class="card-header">
440
- <h4 class="en">Top 5 Cheapest Crops</h4>
441
- <h4 class="mr" style="display:none;">सर्वात स्वस्त 5 पिके</h4>
442
- </div>
443
- <div class="card-body" id="cheapestCrops">
444
  </div>
445
- </div>
446
  </div>
447
- <div class="col-md-6 mb-4">
448
- <div class="card">
449
- <div class="card-header">
450
- <h4 class="en">Top 5 Costliest Crops</h4>
451
- <h4 class="mr" style="display:none;">सर्वात महाग 5 पिके</h4>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
452
  </div>
453
- <div class="card-body" id="costliestCrops">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  </div>
455
- </div>
456
- </div>
457
- </div>
458
 
459
- <div class="card mb-4">
460
- <div class="card-header">
461
- <h4 class="en">Market Data</h4>
462
- <h4 class="mr" style="display:none;">बाजार माहिती</h4>
 
 
 
463
  </div>
464
- <div class="card-body" id="marketData">
 
465
  </div>
466
- </div>
467
  </div>
468
 
469
- <div class="insights-container">
470
- <div id="aiInsights"></div>
471
- </div>
472
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
473
 
474
- <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
475
- <script>
476
- let currentLang = 'en';
477
 
478
- // Update label texts based on translations from the server
479
- function updateLabels(translations) {
480
- if (currentLang === 'mr') {
481
- Object.keys(translations).forEach(key => {
482
- $(.label-${key}).text(translations[key]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483
  });
484
- $('.en').hide();
485
- $('.mr').show();
486
- } else {
487
- $('.label-state').text('State');
488
- $('.label-district').text('District');
489
- $('.label-market').text('Market');
490
- $('.label-commodity').text('Commodity');
491
- $('.en').show();
492
- $('.mr').hide();
493
- }
494
- }
495
 
496
- // Toggle the language and update content
497
- function toggleLanguage() {
498
- currentLang = currentLang === 'en' ? 'mr' : 'en';
499
- $('#langToggle').text(currentLang === 'en' ? 'भाषा बदला | Change Language' : 'भाषा बदला | Change Language');
500
- updateContent();
501
- }
 
 
 
 
 
 
 
 
 
 
 
502
 
503
- // Show and hide the loading indicator
504
- function showLoading() {
505
- $('#loadingIndicator').show();
506
- }
507
- function hideLoading() {
508
- $('#loadingIndicator').hide();
509
- }
 
 
 
 
 
 
 
 
 
 
510
 
511
- // Enable/disable a select element by its id
512
- function enableSelect(selectId) {
513
- $(#${selectId}).prop('disabled', false);
514
- }
515
- function disableSelect(selectId) {
516
- $(#${selectId}).prop('disabled', true);
517
- }
518
 
519
- // Update content by sending the form data (with language info) to the backend
520
- function updateContent() {
521
- showLoading();
522
- const formData = new FormData($('#filterForm')[0]);
523
- formData.append('language', currentLang);
524
 
525
- $.ajax({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
526
  url: '/filter_data',
527
  method: 'POST',
528
  data: formData,
529
  processData: false,
530
  contentType: false,
531
  success: function(response) {
532
- if (response.success) {
533
- // Update plots
534
- if (response.plots.bar) $('#barChart').html(response.plots.bar);
535
- if (response.plots.line) $('#lineChart').html(response.plots.line);
536
- if (response.plots.box) $('#boxChart').html(response.plots.box);
537
-
538
- // Update market statistics
539
- $('#totalCommodities').text(response.market_stats.total_commodities);
540
- $('#avgPrice').text(response.market_stats.avg_modal_price);
541
- $('#priceRange').text(response.market_stats.price_range);
542
- $('#totalMarkets').text(response.market_stats.total_markets);
543
-
544
- // Update tables
545
- $('#marketData').html(response.market_html);
546
- $('#cheapestCrops').html(response.cheapest_html);
547
- $('#costliestCrops').html(response.costliest_html);
548
-
549
- // Show insights only if state and district are selected
550
- if (response.hasStateDistrict) {
551
- $('.insights-container').show();
552
- $('#aiInsights').html(response.insights);
553
  } else {
554
- $('.insights-container').hide();
555
- $('#aiInsights').html('');
556
  }
557
-
558
- // Update translations for labels
559
- updateLabels(response.translations);
560
- console.log(response.translations);
561
- } else {
562
- const message = currentLang === 'en' ?
563
- 'Please select both state and district to view analysis' :
564
- 'कृपया विश्लेषण पाहण्यासाठी राज्य आणि जिल्हा निवडा';
565
- alert(message);
566
- }
567
- hideLoading();
568
  },
569
  error: function() {
570
- alert(currentLang === 'en' ? 'Error loading data' : 'माहिती लोड करताना त्रुटी');
571
- hideLoading();
572
  }
573
- });
574
- }
575
-
576
- // Cascade dropdowns
577
- $('#state').change(function() {
578
- const state = $(this).val();
579
- // Reset and disable dependent dropdowns
580
- $('#district, #market, #commodity').html('<option value="">Select</option>').prop('disabled', true);
581
-
582
- if (state) {
583
- showLoading();
584
- $.post('/get_districts', { state: state }, function(districts) {
585
- $('#district').html('<option value="">Select District</option>');
586
- districts.forEach(district => {
587
- $('#district').append(<option value="${district}">${district}</option>);
588
- });
589
- enableSelect('district');
590
- hideLoading();
591
- });
592
- }
593
- updateContent();
594
- });
595
-
596
- $('#district').change(function() {
597
- const district = $(this).val();
598
- // Reset and disable dependent dropdowns
599
- $('#market, #commodity').html('<option value="">Select</option>').prop('disabled', true);
600
-
601
- if (district) {
602
- showLoading();
603
- $.post('/get_markets', { district: district }, function(markets) {
604
- $('#market').html('<option value="">Select Market</option>');
605
- markets.forEach(market => {
606
- $('#market').append(<option value="${market}">${market}</option>);
607
- });
608
- enableSelect('market');
609
- hideLoading();
610
- });
611
- }
612
- updateContent();
613
- });
614
-
615
- $('#market').change(function() {
616
- const market = $(this).val();
617
- // Reset commodity dropdown
618
- $('#commodity').html('<option value="">Select</option>').prop('disabled', true);
619
-
620
- if (market) {
621
- showLoading();
622
- $.post('/get_commodities', { market: market }, function(commodities) {
623
- $('#commodity').html('<option value="">Select Commodity</option>');
624
- commodities.forEach(commodity => {
625
- $('#commodity').append(<option value="${commodity}">${commodity}</option>);
626
- });
627
- enableSelect('commodity');
628
- hideLoading();
629
- });
630
- }
631
- updateContent();
632
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
633
 
634
- $('#commodity').change(function() {
635
- updateContent();
636
- });
 
 
 
637
 
638
- // Initial setup
639
- $(document).ready(function() {
640
- $('.insights-container').hide();
641
- updateContent();
642
- });
643
- </script>
644
  </body>
645
- </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Crop Market Analysis</title>
7
+ <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
8
+ <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
9
+ <style>
10
+ :root {
11
+ --primary-color: #4CAF50;
12
+ --secondary-color: #45a049;
13
+ --background-color: #f9f9f9;
14
+ --text-color: #333;
15
+ --card-shadow: 0 2px 4px rgba(0,0,0,0.1);
16
+ --border-radius: 8px;
17
+ }
18
+
19
+ body {
20
+ background-color: var(--background-color);
21
+ color: var(--text-color);
22
+ font-family: 'Arial', sans-serif;
23
+ line-height: 1.6;
24
+ }
25
+
26
+ .container {
27
+ max-width: 1200px;
28
+ margin: 0 auto;
29
+ padding: 20px;
30
+ }
31
+
32
+ .header {
33
+ text-align: center;
34
+ margin-bottom: 30px;
35
+ padding: 20px 0;
36
+ }
37
+
38
+ .header h1 {
39
+ color: var(--primary-color);
40
+ font-weight: bold;
41
+ margin: 0;
42
+ font-size: 2.5rem;
43
+ }
44
+
45
+ .form-section {
46
+ background: white;
47
+ padding: 25px;
48
+ border-radius: var(--border-radius);
49
+ box-shadow: var(--card-shadow);
50
+ margin-bottom: 30px;
51
+ }
52
+
53
+ .chart-container {
54
+ background: white;
55
+ padding: 25px;
56
+ border-radius: var(--border-radius);
57
+ box-shadow: var(--card-shadow);
58
+ margin-bottom: 30px;
59
+ }
60
+
61
+ .insights-container {
62
+ background: white;
63
+ padding: 25px;
64
+ border-radius: var(--border-radius);
65
+ box-shadow: var(--card-shadow);
66
+ margin-bottom: 30px;
67
+ border-left: 5px solid var(--primary-color);
68
+ }
69
+
70
+ .insights-container h3 {
71
+ color: var(--primary-color);
72
+ margin-bottom: 20px;
73
+ }
74
+
75
+ .loading {
76
+ display: none;
77
+ text-align: center;
78
+ padding: 20px;
79
+ background: rgba(255, 255, 255, 0.9);
80
+ position: fixed;
81
+ top: 50%;
82
+ left: 50%;
83
+ transform: translate(-50%, -50%);
84
+ border-radius: var(--border-radius);
85
+ box-shadow: var(--card-shadow);
86
+ z-index: 1000;
87
+ }
88
+
89
+ .btn-custom {
90
+ background-color: var(--primary-color);
91
+ color: white;
92
+ border: none;
93
+ padding: 8px 16px;
94
+ border-radius: 4px;
95
+ transition: background-color 0.3s ease;
96
+ }
97
+
98
+ .btn-custom:hover {
99
+ background-color: var(--secondary-color);
100
+ color: white;
101
+ }
102
+
103
+ .form-control {
104
+ border-radius: 4px;
105
+ border: 1px solid #ddd;
106
+ padding: 8px 12px;
107
+ height: auto;
108
+ }
109
+
110
+ .form-control:focus {
111
+ border-color: var(--primary-color);
112
+ box-shadow: 0 0 0 0.2rem rgba(76, 175, 80, 0.25);
113
+ }
114
+
115
+ label {
116
+ font-weight: 500;
117
+ margin-bottom: 8px;
118
+ color: var(--text-color);
119
+ }
120
+
121
+ #barChart, #lineChart, #boxChart {
122
+ width: 100%;
123
+ margin-bottom: 20px;
124
+ }
125
+
126
+ #aiInsights {
127
+ line-height: 1.8;
128
+ font-size: 1.1rem;
129
+ }
130
+
131
+ .alert {
132
+ border-radius: var(--border-radius);
133
+ padding: 15px 20px;
134
+ margin-bottom: 20px;
135
+ }
136
+
137
+ .spinner-border {
138
+ width: 3rem;
139
+ height: 3rem;
140
+ color: var(--primary-color);
141
+ }
142
+
143
+ #marketData {
144
+ height: 600px;
145
+ overflow-y: scroll;
146
+ }
147
+
148
+ .table-responsive{
149
+ height: 600px;
150
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
+ .insights-header {
153
+ background: #4CAF50;
154
+ color: white;
155
+ padding: 15px 20px;
156
+ border-radius: 8px 8px 0 0;
157
+ margin: -25px -25px 20px -25px;
158
+ }
159
+
160
+ .insights-header h3 {
161
+ margin: 0;
162
+ color: white;
163
+ }
164
+
165
+ .insight-section {
166
+ background: #f8f9fa;
167
+ border-radius: 8px;
168
+ padding: 20px;
169
+ margin-bottom: 20px;
170
+ border-left: 4px solid #4CAF50;
171
+ }
172
+
173
+ .insight-section h4 {
174
+ color: #2E7D32;
175
+ margin-bottom: 15px;
176
+ font-size: 1.2rem;
177
+ font-weight: bold;
178
+ }
179
+
180
+ .insight-card {
181
+ background: white;
182
+ border-radius: 6px;
183
+ padding: 15px;
184
+ margin-bottom: 15px;
185
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
186
+ }
187
+
188
+ .insight-card h5 {
189
+ color: #1B5E20;
190
+ margin-bottom: 10px;
191
+ font-size: 1.1rem;
192
+ }
193
+
194
+ .insight-list {
195
+ list-style: none;
196
+ padding-left: 0;
197
+ margin-bottom: 0;
198
+ }
199
+
200
+ .insight-list li {
201
+ position: relative;
202
+ padding-left: 20px;
203
+ margin-bottom: 8px;
204
+ line-height: 1.5;
205
+ }
206
+
207
+ .insight-list li:before {
208
+ content: "•";
209
+ color: #4CAF50;
210
+ font-size: 1.2em;
211
+ position: absolute;
212
+ left: 0;
213
+ top: -2px;
214
+ }
215
+
216
+ .price-highlight {
217
+ color: #2E7D32;
218
+ font-weight: bold;
219
+ }
220
+
221
+ .percentage-up {
222
+ color: #2E7D32;
223
+ font-weight: bold;
224
+ }
225
+
226
+ .percentage-down {
227
+ color: #c62828;
228
+ font-weight: bold;
229
+ }
230
+
231
+ .action-box {
232
+ background: #E8F5E9;
233
+ border-radius: 6px;
234
+ padding: 15px;
235
+ margin-top: 20px;
236
+ border: 1px dashed #4CAF50;
237
+ }
238
+
239
+ .action-box h5 {
240
+ color: #2E7D32;
241
+ margin-bottom: 10px;
242
+ font-size: 1.1rem;
243
+ }
244
+
245
+ .action-list {
246
+ list-style: none;
247
+ padding-left: 0;
248
+ margin-bottom: 0;
249
+ }
250
+
251
+ .action-list li {
252
+ position: relative;
253
+ padding-left: 25px;
254
+ margin-bottom: 8px;
255
+ line-height: 1.5;
256
+ }
257
+
258
+ .action-list li:before {
259
+ content: "✓";
260
+ color: #4CAF50;
261
+ position: absolute;
262
+ left: 0;
263
+ font-weight: bold;
264
+ }
265
+
266
+ @media (max-width: 768px) {
267
+ .insights-container {
268
+ padding: 15px;
269
+ }
270
+
271
+ .insights-header {
272
+ padding: 12px 15px;
273
+ margin: -15px -15px 15px -15px;
274
+ }
275
+
276
+ .insight-section {
277
+ padding: 15px;
278
+ }
279
+ }
280
+ @media (max-width: 768px) {
281
+ .container {
282
+ padding: 10px;
283
+ }
284
+
285
+ .header h1 {
286
+ font-size: 2rem;
287
+ }
288
+
289
+ .form-row {
290
+ flex-direction: column;
291
+ }
292
+
293
+ .form-group {
294
+ margin-bottom: 15px;
295
+ }
296
+
297
+ .btn-custom {
298
+ width: 100%;
299
+ }
300
+
301
+ .insights-container {
302
+ padding: 15px;
303
+ }
304
+
305
+ #aiInsights {
306
+ font-size: 1rem;
307
+ }
308
+ }
309
+ .language-selector {
310
+ margin-top: 10px;
311
+ }
312
+
313
+ .lang-btn {
314
+ font-size: 0.85rem;
315
+ padding: 0.25rem 0.5rem;
316
+ margin: 0 2px;
317
+ border-radius: 4px;
318
+ }
319
+
320
+ .lang-btn.active {
321
+ background-color: #4CAF50;
322
+ color: white;
323
+ }
324
+
325
+ .current-language-indicator {
326
+ font-size: 0.8rem;
327
+ color: #555;
328
+ margin: 5px 0 15px 0;
329
+ }
330
+
331
+ /* For mobile responsiveness */
332
+ @media (max-width: 768px) {
333
+ .language-selector .btn-group {
334
+ display: flex;
335
+ flex-wrap: wrap;
336
+ justify-content: center;
337
+ }
338
+
339
+ .lang-btn {
340
+ margin: 2px;
341
+ flex: 0 0 auto;
342
+ }
343
+ }
344
+ select {
345
+ max-height: 200px;
346
+ overflow-y: auto;
347
+ }
348
 
349
+ .audio-player-container {
350
+ background: #e8f5e9;
351
+ padding: 12px;
352
+ border-radius: 8px;
353
+ margin: 10px 0 0 20px;
354
+ display: inline-block;
355
+ vertical-align: middle;
356
+ }
357
+
358
+ .audio-player-container h4 {
359
+ color: #2E7D32;
360
+ margin: 0 0 8px 0;
361
+ font-size: 0.9rem;
362
+ font-weight: bold;
363
+ }
364
+
365
+ .audio-player-container audio {
366
+ height: 35px;
367
+ vertical-align: middle;
368
+ }
369
+
370
+ #playAudioBtn {
371
+ background-color: #4CAF50;
372
+ color: white;
373
+ border: none;
374
+ margin-left: 5px;
375
+ font-size: 0.85em;
376
+ }
377
+
378
+ #playAudioBtn:hover {
379
+ background-color: #45a049;
380
+ }
381
+
382
  @media (max-width: 768px) {
383
+ .insights-header {
384
+ display: flex;
385
+ flex-direction: column;
386
+ }
387
+
388
+ .audio-player-container {
389
+ margin: 10px 0 0 0;
390
+ width: 100%;
391
+ }
392
+
393
+ .audio-player-container audio {
394
+ width: 100%;
395
+ }
396
+
397
+ #playAudioBtn {
398
+ display: block;
399
+ width: 100%;
400
+ margin: 5px 0 0 0;
401
+ }
402
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
 
404
+ /* Add FontAwesome for play/pause icons */
405
+ .fa {
406
+ display: inline-block;
407
+ font: normal normal normal 14px/1 FontAwesome;
408
+ font-size: inherit;
409
+ text-rendering: auto;
410
+ -webkit-font-smoothing: antialiased;
411
+ -moz-osx-font-smoothing: grayscale;
412
+ }
413
+ .fa-play:before {
414
+ content: "\f04b";
415
  }
416
+ .fa-pause:before {
417
+ content: "\f04c";
 
418
  }
419
+ </style>
420
  </head>
421
  <body>
422
+ <div class="container">
423
+ <div class="header">
424
+ <h1>Crop Market Analysis</h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
425
  </div>
 
 
 
 
 
 
 
 
426
 
427
+ <div class="form-section">
428
+ <form id="filterForm">
429
+ <div class="form-row">
430
+ <div class="form-group col-md-3">
431
+ <label for="state">State</label>
432
+ <select class="form-control" id="state" name="state">
433
+ <option value="">Select State</option>
434
+ {% for state in states %}
435
+ <option value="{{ state }}">{{ state }}</option>
436
+ {% endfor %}
437
+ </select>
438
+ </div>
439
+ <div class="form-group col-md-3">
440
+ <label for="district">District</label>
441
+ <select class="form-control" id="district" name="district" disabled>
442
+ <option value="">Select District</option>
443
+ </select>
444
+ </div>
445
+ <div class="form-group col-md-3">
446
+ <label for="market">Market</label>
447
+ <select class="form-control" id="market" name="market" disabled>
448
+ <option value="">Select Market</option>
449
+ </select>
450
+ </div>
451
+ <div class="form-group col-md-3">
452
+ <label for="commodity">Commodity</label>
453
+ <select class="form-control" id="commodity" name="commodity" disabled>
454
+ <option value="">Select Commodity</option>
455
+ </select>
456
+ </div>
457
  </div>
458
+ <div class="language-selector">
459
+ <div class="card">
460
+ <div class="card-body">
461
+ <h5 class="card-title">Select Language for AI Insights</h5>
462
+ <div class="btn-group" role="group" aria-label="Language selection">
463
+ <button type="button" class="btn btn-sm lang-btn active" data-lang="English">English</button>
464
+ <button type="button" class="btn btn-sm lang-btn" data-lang="Hindi">हिन्दी</button>
465
+ <button type="button" class="btn btn-sm lang-btn" data-lang="Tamil">தமிழ்</button>
466
+ <button type="button" class="btn btn-sm lang-btn" data-lang="Telugu">తెలుగు</button>
467
+ <button type="button" class="btn btn-sm lang-btn" data-lang="Marathi">मराठी</button>
468
+ <button type="button" class="btn btn-sm lang-btn" data-lang="Bengali">বাংলা</button>
469
+ <button type="button" class="btn btn-sm lang-btn" data-lang="Gujarati">ગુજરાતી</button>
470
+ <button type="button" class="btn btn-sm lang-btn" data-lang="Kannada">ಕನ್ನಡ</button>
471
+ <button type="button" class="btn btn-sm lang-btn" data-lang="Malayalam">മലയാളം</button>
472
+ <button type="button" class="btn btn-sm lang-btn" data-lang="Punjabi">ਪੰਜਾਬੀ</button>
473
+ </div>
474
+ <div class="current-language-indicator mt-2">
475
+ Current language: <span id="currentLanguage">English</span>
476
+ </div>
477
+ </div>
478
+ </div>
479
  </div>
480
+ </form>
 
 
 
 
 
 
 
 
 
481
  </div>
 
482
 
483
+ <div class="loading" id="loadingIndicator">
484
+ <div class="spinner-border" role="status">
485
+ <span class="sr-only">Loading...</span>
 
 
 
 
 
486
  </div>
 
487
  </div>
488
+
489
+ <div class="chart-container">
490
+ <div id="barChart"></div>
491
+ <div id="lineChart"></div>
492
+ <div id="boxChart"></div>
493
+ </div>
494
+ <div class="market-data-container">
495
+ <div class="row">
496
+ <div class="col-md-12 mb-4">
497
+ <div class="card">
498
+ <div class="card-header">
499
+ <h4>Market Statistics</h4>
500
+ </div>
501
+ <div class="card-body">
502
+ <div class="row">
503
+ <div class="col-md-3">
504
+ <div class="stat-item">
505
+ <h6>Total Commodities</h6>
506
+ <span id="totalCommodities"></span>
507
+ </div>
508
+ </div>
509
+ <div class="col-md-3">
510
+ <div class="stat-item">
511
+ <h6>Average Price</h6>
512
+ <span id="avgPrice"></span>
513
+ </div>
514
+ </div>
515
+ <div class="col-md-3">
516
+ <div class="stat-item">
517
+ <h6>Price Range</h6>
518
+ <span id="priceRange"></span>
519
+ </div>
520
+ </div>
521
+ <div class="col-md-3">
522
+ <div class="stat-item">
523
+ <h6>Total Markets</h6>
524
+ <span id="totalMarkets"></span>
525
+ </div>
526
+ </div>
527
+ </div>
528
+ </div>
529
+ </div>
530
+ </div>
531
  </div>
532
+
533
+ <div class="row">
534
+ <div class="col-md-6 mb-4">
535
+ <div class="card">
536
+ <div class="card-header">
537
+ <h4>Top 5 Cheapest Crops</h4>
538
+ </div>
539
+ <div class="card-body" id="cheapestCrops">
540
+ </div>
541
+ </div>
542
+ </div>
543
+ <div class="col-md-6 mb-4">
544
+ <div class="card">
545
+ <div class="card-header">
546
+ <h4>Top 5 Costliest Crops</h4>
547
+ </div>
548
+ <div class="card-body" id="costliestCrops">
549
+ </div>
550
+ </div>
551
+ </div>
552
  </div>
 
 
 
553
 
554
+ <div class="card mb-4">
555
+ <div class="card-header">
556
+ <h4>Market Data</h4>
557
+ </div>
558
+ <div class="card-body" id="marketData">
559
+ </div>
560
+ </div>
561
  </div>
562
+ <div class="insights-container">
563
+ <div id="aiInsights"></div>
564
  </div>
 
565
  </div>
566
 
567
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
568
+ <script>
569
+ // Add this to your JavaScript
570
+ function updateAudioPlayer(audioPath) {
571
+ if (audioPath) {
572
+ $('#audioPlayerContainer').show();
573
+ $('#insightsAudio').attr('src', audioPath);
574
+ } else {
575
+ $('#audioPlayerContainer').hide();
576
+ }
577
+ }
578
+ function showLoading() {
579
+ $('#loadingIndicator').show();
580
+ }
581
+
582
+ function hideLoading() {
583
+ $('#loadingIndicator').hide();
584
+ }
585
+
586
+ function enableSelect(selectId) {
587
+ $(`#${selectId}`).prop('disabled', false);
588
+ }
589
 
590
+ function disableSelect(selectId) {
591
+ $(`#${selectId}`).prop('disabled', true);
592
+ }
593
 
594
+ function updateContent() {
595
+ showLoading();
596
+ const formData = new FormData($('#filterForm')[0]);
597
+
598
+ $.ajax({
599
+ url: '/filter_data',
600
+ method: 'POST',
601
+ data: formData,
602
+ processData: false,
603
+ contentType: false,
604
+ success: function(response) {
605
+ if (response.success) {
606
+ if (response.plots.bar) $('#barChart').html(response.plots.bar);
607
+ if (response.plots.line) $('#lineChart').html(response.plots.line);
608
+ if (response.plots.box) $('#boxChart').html(response.plots.box);
609
+
610
+ $('#totalCommodities').text(response.market_stats.total_commodities);
611
+ $('#avgPrice').text(response.market_stats.avg_modal_price);
612
+ $('#priceRange').text(response.market_stats.price_range);
613
+ $('#totalMarkets').text(response.market_stats.total_markets);
614
+
615
+ $('#marketData').html(response.market_html);
616
+ $('#cheapestCrops').html(response.cheapest_html);
617
+ $('#costliestCrops').html(response.costliest_html);
618
+
619
+ if (response.hasStateDistrict) {
620
+ $('.insights-container').show();
621
+ $('#aiInsights').html(response.insights);
622
+ } else {
623
+ $('.insights-container').hide();
624
+ $('#aiInsights').html('');
625
+ }
626
+ } else {
627
+ alert('Please select both state and district to view analysis');
628
+ }
629
+ hideLoading();
630
+ },
631
+ error: function() {
632
+ alert('Error loading data');
633
+ hideLoading();
634
+ }
635
+ });
636
+ }
637
+
638
+ $('#state').change(function() {
639
+ const state = $(this).val();
640
+ $('#district, #market, #commodity').html('<option value="">Select</option>').prop('disabled', true);
641
+
642
+ if (state) {
643
+ showLoading();
644
+ $.post('/get_districts', { state: state }, function(districts) {
645
+ $('#district').html('<option value="">Select District</option>');
646
+ districts.forEach(district => {
647
+ $('#district').append(`<option value="${district}">${district}</option>`);
648
+ });
649
+ enableSelect('district');
650
+ hideLoading();
651
+ });
652
+ }
653
+ updateContent();
654
  });
 
 
 
 
 
 
 
 
 
 
 
655
 
656
+ $('#district').change(function() {
657
+ const district = $(this).val();
658
+ $('#market, #commodity').html('<option value="">Select</option>').prop('disabled', true);
659
+
660
+ if (district) {
661
+ showLoading();
662
+ $.post('/get_markets', { district: district }, function(markets) {
663
+ $('#market').html('<option value="">Select Market</option>');
664
+ markets.forEach(market => {
665
+ $('#market').append(`<option value="${market}">${market}</option>`);
666
+ });
667
+ enableSelect('market');
668
+ hideLoading();
669
+ });
670
+ }
671
+ updateContent();
672
+ });
673
 
674
+ $('#market').change(function() {
675
+ const market = $(this).val();
676
+ $('#commodity').html('<option value="">Select</option>').prop('disabled', true);
677
+
678
+ if (market) {
679
+ showLoading();
680
+ $.post('/get_commodities', { market: market }, function(commodities) {
681
+ $('#commodity').html('<option value="">Select Commodity</option>');
682
+ commodities.forEach(commodity => {
683
+ $('#commodity').append(`<option value="${commodity}">${commodity}</option>`);
684
+ });
685
+ enableSelect('commodity');
686
+ hideLoading();
687
+ });
688
+ }
689
+ updateContent();
690
+ });
691
 
692
+ $('#commodity').change(function() {
693
+ updateContent();
694
+ });
 
 
 
 
695
 
696
+ $(document).ready(function() {
697
+ $('.insights-container').hide();
698
+ updateContent();
699
+ });
 
700
 
701
+ // Language handling
702
+ let currentLanguage = "English";
703
+
704
+ $('.lang-btn').click(function() {
705
+ $('.lang-btn').removeClass('active');
706
+ $(this).addClass('active');
707
+ currentLanguage = $(this).data('lang');
708
+ $('#currentLanguage').text(currentLanguage);
709
+
710
+ // If state and district are selected, update the content to reflect the new language
711
+ if ($('#state').val() && $('#district').val()) {
712
+ updateContent();
713
+ }
714
+ });
715
+
716
+ // Modify the updateContent function to include language
717
+ function updateContent() {
718
+ showLoading();
719
+ const formData = new FormData($('#filterForm')[0]);
720
+
721
+ // Add language to form data
722
+ formData.append('language', currentLanguage);
723
+
724
+ $.ajax({
725
  url: '/filter_data',
726
  method: 'POST',
727
  data: formData,
728
  processData: false,
729
  contentType: false,
730
  success: function(response) {
731
+ if (response.success) {
732
+ if (response.plots.bar) $('#barChart').html(response.plots.bar);
733
+ if (response.plots.line) $('#lineChart').html(response.plots.line);
734
+ if (response.plots.box) $('#boxChart').html(response.plots.box);
735
+
736
+ $('#totalCommodities').text(response.market_stats.total_commodities);
737
+ $('#avgPrice').text(response.market_stats.avg_modal_price);
738
+ $('#priceRange').text(response.market_stats.price_range);
739
+ $('#totalMarkets').text(response.market_stats.total_markets);
740
+
741
+ $('#marketData').html(response.market_html);
742
+ $('#cheapestCrops').html(response.cheapest_html);
743
+ $('#costliestCrops').html(response.costliest_html);
744
+
745
+ if (response.hasStateDistrict) {
746
+ $('.insights-container').show();
747
+ $('#aiInsights').html(response.insights);
748
+ } else {
749
+ $('.insights-container').hide();
750
+ $('#aiInsights').html('');
751
+ }
752
  } else {
753
+ alert('Please select both state and district to view analysis');
 
754
  }
755
+ hideLoading();
 
 
 
 
 
 
 
 
 
 
756
  },
757
  error: function() {
758
+ alert('Error loading data');
759
+ hideLoading();
760
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
761
  });
762
+ }
763
+ // Add this in the <head> section after the jQuery import
764
+
765
+ $(document).on('click', '#playAudioBtn', function() {
766
+ const audioPlayer = document.getElementById('insightsAudio');
767
+
768
+ if (audioPlayer) {
769
+ if (audioPlayer.paused) {
770
+ audioPlayer.play();
771
+ $(this).html('<i class="fa fa-pause"></i> Pause Audio');
772
+ } else {
773
+ audioPlayer.pause();
774
+ $(this).html('<i class="fa fa-play"></i> Play Audio');
775
+ }
776
+ }
777
+ });
778
 
779
+ // Reset play button text when audio ends
780
+ $(document).on('ended', '#insightsAudio', function() {
781
+ $('#playAudioBtn').html('<i class="fa fa-play"></i> Play Audio');
782
+ });
783
+ </script>
784
+ <script src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"></script>
785
 
 
 
 
 
 
 
786
  </body>
787
+ </html>