Rajkhanke007 commited on
Commit
b03cd41
·
verified ·
1 Parent(s): 2cd0882

Create templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +572 -0
templates/index.html ADDED
@@ -0,0 +1,572 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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" />
6
+ <title>Pest Outbreak Prediction System</title>
7
+ <!-- Bootstrap CSS (for grid utilities) -->
8
+ <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet" />
9
+ <!-- Tailwind CSS CDN for advanced styling -->
10
+ <script src="https://cdn.tailwindcss.com"></script>
11
+ <!-- Leaflet CSS for map -->
12
+ <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
13
+ <!-- Leaflet Control Geocoder CSS for search bar -->
14
+ <link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" />
15
+ <style>
16
+ @media (max-width: 480px) {
17
+ .container-custom {
18
+ padding: 0.2rem;
19
+ border-radius: 6px;
20
+ margin: 0.2rem;
21
+ }
22
+ .form-section {
23
+ padding: 0.5rem;
24
+ margin-bottom: 0.5rem;
25
+ border-radius: 0.3rem;
26
+ }
27
+ h1 {
28
+ font-size: 1.1rem;
29
+ margin-bottom: 0.5rem;
30
+ }
31
+ h4 {
32
+ font-size: 0.95rem;
33
+ margin-bottom: 0.5rem;
34
+ }
35
+ .weather-card {
36
+ padding: 0.5rem;
37
+ font-size: 0.85rem;
38
+ margin-bottom: 0.3rem;
39
+ }
40
+ .btn-success, .btn-primary {
41
+ font-size: 0.9rem;
42
+ padding: 0.4rem 0.7rem;
43
+ border-radius: 5px;
44
+ }
45
+ #map {
46
+ height: 140px;
47
+ border-radius: 0.3rem;
48
+ }
49
+ .form-control {
50
+ font-size: 0.9rem;
51
+ padding: 0.3rem 0.4rem;
52
+ }
53
+ }
54
+ @media (max-width: 768px) {
55
+ .container-custom {
56
+ padding: 0.5rem;
57
+ border-radius: 8px;
58
+ margin: 0.5rem;
59
+ }
60
+ .form-section {
61
+ padding: 1rem;
62
+ margin-bottom: 1rem;
63
+ border-radius: 0.5rem;
64
+ }
65
+ h1 {
66
+ font-size: 1.5rem;
67
+ margin-bottom: 1rem;
68
+ }
69
+ h4 {
70
+ font-size: 1.1rem;
71
+ margin-bottom: 1rem;
72
+ }
73
+ .weather-card {
74
+ padding: 0.75rem;
75
+ font-size: 0.95rem;
76
+ margin-bottom: 0.5rem;
77
+ }
78
+ .btn-success, .btn-primary {
79
+ font-size: 1rem;
80
+ padding: 0.5rem 1rem;
81
+ border-radius: 6px;
82
+ }
83
+ #map {
84
+ height: 220px;
85
+ border-radius: 0.5rem;
86
+ }
87
+ .grid {
88
+ display: block !important;
89
+ }
90
+ .flex {
91
+ flex-direction: column !important;
92
+ padding: 0 !important;
93
+ }
94
+ .form-control {
95
+ font-size: 1rem;
96
+ padding: 0.4rem 0.6rem;
97
+ }
98
+ }
99
+ body {
100
+ margin: 0;
101
+ padding: 0;
102
+ min-height: 100vh;
103
+ background: linear-gradient(120deg, #e8f5e9 0%, #f7f7f7 100%), url('https://images.unsplash.com/photo-1506744038136-46273834b3fb?auto=format&fit=crop&w=1200&q=80');
104
+ background-size: cover;
105
+ background-repeat: no-repeat;
106
+ background-position: center;
107
+ }
108
+ .container-custom {
109
+ max-width: 1200px;
110
+ margin: 2rem auto;
111
+ padding: 2rem 1rem;
112
+ background: rgba(255,255,255,0.95);
113
+ border-radius: 16px;
114
+ box-shadow: 0 8px 32px rgba(56,142,60,0.15), 0 1.5px 8px rgba(0,0,0,0.08);
115
+ border: 2px solid #81c784;
116
+ position: relative;
117
+ overflow: hidden;
118
+ }
119
+ #map {
120
+ height: 400px;
121
+ border-radius: 0.75rem;
122
+ box-shadow: 0 8px 16px rgba(0,0,0,0.1);
123
+ }
124
+ .form-section {
125
+ background: linear-gradient(120deg, #e0f7fa 0%, #f1f8e9 100%);
126
+ border-radius: 1rem;
127
+ box-shadow: 0 8px 24px rgba(56,142,60,0.10);
128
+ padding: 2rem;
129
+ margin-bottom: 2rem;
130
+ border: 1.5px solid #c8e6c9;
131
+ transition: transform 0.3s, box-shadow 0.3s;
132
+ position: relative;
133
+ }
134
+ .form-section:hover {
135
+ transform: translateY(-6px) scale(1.01);
136
+ box-shadow: 0 16px 32px rgba(56,142,60,0.18);
137
+ border-color: #388e3c;
138
+ }
139
+ h1 {
140
+ color: #388e3c;
141
+ text-align: center;
142
+ font-family: 'Merriweather', serif;
143
+ letter-spacing: 1px;
144
+ background: linear-gradient(to right, #a5d6a7, #388e3c);
145
+ -webkit-background-clip: text;
146
+ -webkit-text-fill-color: transparent;
147
+ margin-bottom: 2rem;
148
+ text-shadow: 0 2px 8px rgba(56,142,60,0.10);
149
+ }
150
+ h4 {
151
+ color: #558b2f;
152
+ text-align: left;
153
+ font-family: 'Merriweather', serif;
154
+ margin-bottom: 1.5rem;
155
+ font-size: 1.5rem;
156
+ font-weight: 700;
157
+ letter-spacing: 0.5px;
158
+ }
159
+ /* Weather Card Styles */
160
+ .weather-card {
161
+ background: linear-gradient(120deg, #e8f5e9 0%, #fff 100%);
162
+ border-radius: 0.75rem;
163
+ box-shadow: 0 2px 8px rgba(56,142,60,0.10);
164
+ padding: 1.25rem;
165
+ text-align: center;
166
+ transition: transform 0.2s, box-shadow 0.2s;
167
+ border: 1px solid #c8e6c9;
168
+ font-family: 'Merriweather', serif;
169
+ }
170
+ .weather-card:hover {
171
+ transform: translateY(-4px) scale(1.03);
172
+ box-shadow: 0 8px 24px rgba(56,142,60,0.18);
173
+ border-color: #388e3c;
174
+ }
175
+ .weather-title {
176
+ font-weight: 700;
177
+ color: #388e3c;
178
+ margin-bottom: 0.5rem;
179
+ font-size: 1.1rem;
180
+ letter-spacing: 0.5px;
181
+ }
182
+ /* Soil properties table styling */
183
+ #soilPropertiesTable table {
184
+ width: 100%;
185
+ border-collapse: collapse;
186
+ font-family: 'Merriweather', serif;
187
+ }
188
+ #soilPropertiesTable th, #soilPropertiesTable td {
189
+ padding: 0.75rem;
190
+ border: 1px solid #c8e6c9;
191
+ text-align: center;
192
+ }
193
+ #soilPropertiesTable th {
194
+ background-color: #388e3c;
195
+ color: #fff;
196
+ font-weight: 700;
197
+ letter-spacing: 0.5px;
198
+ }
199
+ .btn-success {
200
+ background: linear-gradient(90deg, #81c784 0%, #388e3c 100%);
201
+ color: #fff !important;
202
+ border: none;
203
+ border-radius: 8px;
204
+ font-size: 1.25rem;
205
+ font-weight: 700;
206
+ box-shadow: 0 2px 8px rgba(56,142,60,0.10);
207
+ padding: 0.75rem 2.5rem;
208
+ transition: background 0.2s, transform 0.2s;
209
+ letter-spacing: 0.5px;
210
+ font-family: 'Merriweather', serif;
211
+ margin-top: 1rem;
212
+ }
213
+ .btn-success:hover {
214
+ background: linear-gradient(90deg, #388e3c 0%, #81c784 100%);
215
+ transform: scale(1.05);
216
+ box-shadow: 0 8px 24px rgba(56,142,60,0.18);
217
+ }
218
+ .btn-primary {
219
+ background: linear-gradient(90deg, #aed581 0%, #388e3c 100%);
220
+ color: #fff !important;
221
+ border: none;
222
+ border-radius: 8px;
223
+ font-size: 1.1rem;
224
+ font-weight: 600;
225
+ box-shadow: 0 2px 8px rgba(56,142,60,0.10);
226
+ padding: 0.5rem 1.5rem;
227
+ transition: background 0.2s, transform 0.2s;
228
+ font-family: 'Merriweather', serif;
229
+ }
230
+ .btn-primary:hover {
231
+ background: linear-gradient(90deg, #388e3c 0%, #aed581 100%);
232
+ transform: scale(1.05);
233
+ box-shadow: 0 8px 24px rgba(56,142,60,0.18);
234
+ }
235
+ </style>
236
+ </head>
237
+ <body>
238
+ <!-- Loader overlay -->
239
+ <div id="loaderOverlay" style="display:none;position:fixed;top:0;left:0;width:100vw;height:100vh;background:rgba(255,255,255,0.7);z-index:9999;">
240
+ <div style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);">
241
+ <div style="display:flex;flex-direction:column;align-items:center;">
242
+ <div class="spinner-border text-success" style="width:4rem;height:4rem;" role="status">
243
+ <span class="sr-only">Loading...</span>
244
+ </div>
245
+ <div style="margin-top:1rem;font-size:1.25rem;color:#388e3c;font-weight:600;">Generating Report...</div>
246
+ </div>
247
+ </div>
248
+ </div>
249
+ <div class="container container-custom py-8">
250
+ <h1 class="text-4xl font-bold mb-8">Pest Outbreak Prediction System</h1>
251
+ <!-- The form submits to /predict to generate a detailed pest outbreak report -->
252
+ <form id="farmForm" action="/predict" method="post">
253
+ <!-- Map & Manual Inputs -->
254
+ <div class="form-section">
255
+ <h4 class="text-2xl font-semibold mb-4">Select Farm Location</h4>
256
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
257
+ <!-- Left: Satellite map with search bar -->
258
+ <div>
259
+ <div id="map"></div>
260
+ </div>
261
+ <!-- Right: Manual lat/lon input and fetch location -->
262
+ <div class="flex flex-col justify-center space-y-4 p-4">
263
+ <div>
264
+ <label class="font-medium" for="manual_lat">Latitude:</label>
265
+ <input type="number" step="0.000001" id="manual_lat" class="form-control" placeholder="Enter latitude" />
266
+ </div>
267
+ <div>
268
+ <label class="font-medium" for="manual_lon">Longitude:</label>
269
+ <input type="number" step="0.000001" id="manual_lon" class="form-control" placeholder="Enter longitude" />
270
+ </div>
271
+ <button type="button" id="updateLocationBtn" class="btn btn-primary shadow-md hover:shadow-lg transition duration-300">
272
+ Update Location
273
+ </button>
274
+ <button type="button" id="fetchCurrentLocationBtn" class="btn btn-success shadow-md hover:shadow-lg transition duration-300 mt-2">
275
+ Fetch Current Location
276
+ </button>
277
+ </div>
278
+ </div>
279
+ <!-- Hidden fields to store final lat/lon -->
280
+ <input type="hidden" id="latitude" name="latitude" />
281
+ <input type="hidden" id="longitude" name="longitude" />
282
+ </div>
283
+
284
+ <!-- Weather Data Display -->
285
+ <div class="form-section">
286
+ <h4 class="text-2xl font-semibold mb-4">Weather Data</h4>
287
+ <div id="weatherDataContainer" class="grid grid-cols-1 md:grid-cols-4 gap-4">
288
+ <div class="col-span-full text-center text-gray-600">
289
+ Weather data will appear here after you select or update a location.
290
+ </div>
291
+ </div>
292
+ </div>
293
+
294
+
295
+ <!-- Additional Agricultural Inputs -->
296
+ <div class="form-section">
297
+ <h4 class="text-2xl font-semibold mb-4">Additional Agricultural Inputs</h4>
298
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
299
+ <div>
300
+ <label class="font-medium" for="crop_type">Crop Type:</label>
301
+ <select class="form-control" id="crop_type" name="crop_type">
302
+ <option value="rice">Rice</option>
303
+ <option value="wheat">Wheat</option>
304
+ <option value="maize">Maize</option>
305
+ <option value="cotton">Cotton</option>
306
+ <option value="sugarcane">Sugarcane</option>
307
+ <option value="soybean">Soybean</option>
308
+ <option value="millet">Millet</option>
309
+ <option value="pulses">Pulses</option>
310
+ <option value="potato">Potato</option>
311
+ <option value="tomato">Tomato</option>
312
+ <option value="onion">Onion</option>
313
+ <option value="garlic">Garlic</option>
314
+ <option value="groundnut">Groundnut</option>
315
+ <option value="barley">Barley</option>
316
+ <option value="jute">Jute</option>
317
+ <option value="tea">Tea</option>
318
+ <option value="coffee">Coffee</option>
319
+ <option value="sorghum">Sorghum</option>
320
+ <option value="turmeric">Turmeric</option>
321
+ <option value="ginger">Ginger</option>
322
+ </select>
323
+ </div>
324
+ <div>
325
+ <label class="font-medium" for="sowing_date">Plant Sowing Date:</label>
326
+ <input type="date" class="form-control" id="sowing_date" name="sowing_date" />
327
+ </div>
328
+ <div>
329
+ <label class="font-medium" for="harvest_date">Expected Harvest Date:</label>
330
+ <input type="date" class="form-control" id="harvest_date" name="harvest_date" />
331
+ </div>
332
+ <div>
333
+ <label class="font-medium" for="growth_stage">Current Growth Stage:</label>
334
+ <select class="form-control" id="growth_stage" name="growth_stage">
335
+ <option value="sowing">Sowing</option>
336
+ <option value="germination">Germination</option>
337
+ <option value="vegetative">Vegetative</option>
338
+ <option value="flowering">Flowering</option>
339
+ <option value="fruiting">Fruiting</option>
340
+ <option value="harvest">Harvest</option>
341
+ </select>
342
+ </div>
343
+ <div>
344
+ <label class="font-medium" for="irrigation_freq">Irrigation Frequency:</label>
345
+ <select class="form-control" id="irrigation_freq" name="irrigation_freq">
346
+ <option value="daily">Daily</option>
347
+ <option value="alternate">Alternate Day</option>
348
+ <option value="twice_week">Twice a Week</option>
349
+ <option value="weekly">Weekly</option>
350
+ </select>
351
+ </div>
352
+ <div>
353
+ <label class="font-medium" for="irrigation_method">Irrigation Method:</label>
354
+ <select class="form-control" id="irrigation_method" name="irrigation_method">
355
+ <option value="drip">Drip</option>
356
+ <option value="sprinkler">Sprinkler</option>
357
+ <option value="flood">Flood</option>
358
+ <option value="manual">Manual</option>
359
+ </select>
360
+ </div>
361
+ <div>
362
+ <label class="font-medium" for="soil_type">Soil Type:</label>
363
+ <select class="form-control" id="soil_type" name="soil_type">
364
+ <option value="red">Red</option>
365
+ <option value="black">Black</option>
366
+ <option value="clay">Clay</option>
367
+ <option value="sandy">Sandy</option>
368
+ <option value="loamy">Loamy</option>
369
+ </select>
370
+ </div>
371
+ <div class="mb-4">
372
+ <label for="language" class="form-label">Response Language</label>
373
+ <select class="form-control" id="language" name="language" required>
374
+ <option value="English">English</option>
375
+ <option value="Hindi">Hindi</option>
376
+ <option value="Bengali">Bengali</option>
377
+ <option value="Telugu">Telugu</option>
378
+ <option value="Marathi">Marathi</option>
379
+ <option value="Tamil">Tamil</option>
380
+ <option value="Gujarati">Gujarati</option>
381
+ <option value="Urdu">Urdu</option>
382
+ <option value="Kannada">Kannada</option>
383
+ <option value="Odia">Odia</option>
384
+ <option value="Malayalam">Malayalam</option>
385
+ </select>
386
+ </div>
387
+ </div>
388
+ </div>
389
+
390
+ <!-- Hidden Fields for passing Weather data to Gemini -->
391
+ <input type="hidden" id="max_temp_hidden" name="max_temp" />
392
+ <input type="hidden" id="min_temp_hidden" name="min_temp" />
393
+ <input type="hidden" id="current_temp_hidden" name="current_temp" />
394
+ <input type="hidden" id="humidity_hidden" name="humidity" />
395
+ <input type="hidden" id="rainfall_hidden" name="rain" />
396
+ <input type="hidden" id="soil_moisture_hidden" name="soil_moisture" />
397
+ <input type="hidden" id="wind_speed_hidden" name="wind_speed" />
398
+ <input type="hidden" id="cloud_cover_hidden" name="cloud_cover" />
399
+
400
+ <div class="form-section text-center">
401
+ <button type="submit" class="btn btn-success btn-lg shadow-xl transform hover:scale-105 transition duration-300">
402
+ Predict Pest Outbreak
403
+ </button>
404
+ </div>
405
+ </form>
406
+ </div>
407
+
408
+ <!-- Scripts -->
409
+ <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
410
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
411
+ <!-- Leaflet JS -->
412
+ <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
413
+ <!-- Leaflet Control Geocoder JS for search -->
414
+ <script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script>
415
+ <script>
416
+ // Initialize the map using Esri's World Imagery (satellite view)
417
+ var map = L.map('map').setView([20.5937, 78.9629], 5);
418
+ L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
419
+ attribution: 'Tiles © Esri',
420
+ maxZoom: 18,
421
+ }).addTo(map);
422
+
423
+ // Explicitly define the geocoder provider using Nominatim
424
+ var geocoder = L.Control.Geocoder.nominatim();
425
+
426
+ // Add geocoder (search bar) to the map with the provider
427
+ L.Control.geocoder({
428
+ geocoder: geocoder,
429
+ defaultMarkGeocode: false
430
+ })
431
+ .on('markgeocode', function(e) {
432
+ var bbox = e.geocode.bbox;
433
+ var center = e.geocode.center;
434
+ map.fitBounds(bbox);
435
+ setMarker(center);
436
+ })
437
+ .addTo(map);
438
+
439
+ var marker;
440
+ function setMarker(latlng) {
441
+ if (marker) {
442
+ marker.setLatLng(latlng);
443
+ } else {
444
+ marker = L.marker(latlng).addTo(map);
445
+ }
446
+ // Update both hidden and manual fields
447
+ document.getElementById('latitude').value = latlng.lat.toFixed(6);
448
+ document.getElementById('longitude').value = latlng.lng.toFixed(6);
449
+ document.getElementById('manual_lat').value = latlng.lat.toFixed(6);
450
+ document.getElementById('manual_lon').value = latlng.lng.toFixed(6);
451
+
452
+ // Fetch weather and soil data
453
+ fetchWeatherData(latlng.lat, latlng.lng);
454
+ }
455
+
456
+ map.on('click', function(e) {
457
+ setMarker(e.latlng);
458
+ });
459
+
460
+ // Update location using manual input
461
+ document.getElementById('updateLocationBtn').addEventListener('click', function(){
462
+ const lat = parseFloat(document.getElementById('manual_lat').value);
463
+ const lon = parseFloat(document.getElementById('manual_lon').value);
464
+ if(!isNaN(lat) && !isNaN(lon)){
465
+ const latlng = L.latLng(lat, lon);
466
+ map.setView(latlng, 10);
467
+ setMarker(latlng);
468
+ } else {
469
+ alert("Please enter valid latitude and longitude values.");
470
+ }
471
+ });
472
+
473
+ // Fetch current location using Geolocation API
474
+ document.getElementById('fetchCurrentLocationBtn').addEventListener('click', function(){
475
+ if (navigator.geolocation) {
476
+ navigator.geolocation.getCurrentPosition(function(position) {
477
+ const lat = position.coords.latitude;
478
+ const lon = position.coords.longitude;
479
+ document.getElementById('manual_lat').value = lat.toFixed(6);
480
+ document.getElementById('manual_lon').value = lon.toFixed(6);
481
+ const latlng = L.latLng(lat, lon);
482
+ map.setView(latlng, 13);
483
+ setMarker(latlng);
484
+ }, function(error) {
485
+ alert('Unable to fetch current location. Please allow location access and try again.');
486
+ });
487
+ } else {
488
+ alert('Geolocation is not supported by your browser.');
489
+ }
490
+ });
491
+
492
+ // Fetch weather data from backend (/get_weather_data)
493
+ function fetchWeatherData(lat, lng) {
494
+ fetch(`/get_weather_data?lat=${lat}&lon=${lng}`)
495
+ .then(response => response.json())
496
+ .then(data => {
497
+ // Update the weather card container
498
+ const container = document.getElementById('weatherDataContainer');
499
+ container.innerHTML = `
500
+ <div class="weather-card">
501
+ <div class="weather-title">Max Temp</div>
502
+ <div>${data.max_temp !== null ? data.max_temp + " °C" : "Not available"}</div>
503
+ </div>
504
+ <div class="weather-card">
505
+ <div class="weather-title">Min Temp</div>
506
+ <div>${data.min_temp !== null ? data.min_temp + " °C" : "Not available"}</div>
507
+ </div>
508
+ <div class="weather-card">
509
+ <div class="weather-title">Current Temp</div>
510
+ <div>${data.current_temp !== null ? data.current_temp + " °C" : "Not available"}</div>
511
+ </div>
512
+ <div class="weather-card">
513
+ <div class="weather-title">Humidity</div>
514
+ <div>${data.humidity !== null ? data.humidity.toFixed(1) + " %" : "Not available"}</div>
515
+ </div>
516
+ <div class="weather-card">
517
+ <div class="weather-title">Rain</div>
518
+ <div>${data.rainfall !== null ? data.rainfall + " mm" : "Not available"}</div>
519
+ </div>
520
+ <div class="weather-card">
521
+ <div class="weather-title">Soil Moisture</div>
522
+ <div>${data.soil_moisture !== null ? data.soil_moisture.toFixed(1) + " %" : "Not available"}</div>
523
+ </div>
524
+ <div class="weather-card">
525
+ <div class="weather-title">Wind Speed</div>
526
+ <div>${data.wind_speed !== null ? data.wind_speed + " km/h" : "Not available"}</div>
527
+ </div>
528
+ <div class="weather-card">
529
+ <div class="weather-title">Cloud Cover</div>
530
+ <div>${data.cloud_cover !== null ? data.cloud_cover.toFixed(1) + " %" : "Not available"}</div>
531
+ </div>
532
+ `;
533
+
534
+ // Also store these values in hidden fields so they pass to Gemini
535
+ document.getElementById('max_temp_hidden').value = data.max_temp ?? "";
536
+ document.getElementById('min_temp_hidden').value = data.min_temp ?? "";
537
+ document.getElementById('current_temp_hidden').value = data.current_temp ?? "";
538
+ document.getElementById('humidity_hidden').value = data.humidity ?? "";
539
+ document.getElementById('rainfall_hidden').value = data.rainfall ?? "";
540
+ document.getElementById('soil_moisture_hidden').value = data.soil_moisture ?? "";
541
+ document.getElementById('wind_speed_hidden').value = data.wind_speed ?? "";
542
+ document.getElementById('cloud_cover_hidden').value = data.cloud_cover ?? "";
543
+ })
544
+ .catch(error => console.error('Error fetching weather data:', error));
545
+ }
546
+
547
+ // Fetch soil properties from backend (/get_soil_properties)
548
+ function fetchSoilProperties(lat, lng) {
549
+ fetch(`/get_soil_properties?lat=${lat}&lon=${lng}`)
550
+ .then(response => response.json())
551
+ .then(data => {
552
+ if(data.soil_properties) {
553
+ let tableHTML = "<table><thead><tr><th>Parameter</th><th>Value</th><th>Unit</th></tr></thead><tbody>";
554
+ data.soil_properties.forEach(function(item) {
555
+ tableHTML += `<tr><td>${item[0]}</td><td>${item[1]}</td><td>${item[2]}</td></tr>`;
556
+ });
557
+ tableHTML += "</tbody></table>";
558
+ document.getElementById("soilTableContainer").innerHTML = tableHTML;
559
+ } else {
560
+ document.getElementById("soilTableContainer").innerHTML = "<p class='text-center text-gray-600'>No soil data available.</p>";
561
+ }
562
+ })
563
+ .catch(error => console.error('Error fetching soil properties:', error));
564
+ }
565
+
566
+ // Loader logic for form submit
567
+ document.getElementById('farmForm').addEventListener('submit', function(e) {
568
+ document.getElementById('loaderOverlay').style.display = 'block';
569
+ });
570
+ </script>
571
+ </body>
572
+ </html>