Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Crop Market Analysis</title> | |
| <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> | |
| <script src="https://cdn.plot.ly/plotly-latest.min.js"></script> | |
| <style> | |
| :root { | |
| --primary-color: #4CAF50; | |
| --secondary-color: #45a049; | |
| --background-color: #f9f9f9; | |
| --text-color: #333; | |
| --card-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
| --border-radius: 8px; | |
| } | |
| body { | |
| background-color: var(--background-color); | |
| color: var(--text-color); | |
| font-family: 'Arial', sans-serif; | |
| line-height: 1.6; | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| .header { | |
| text-align: center; | |
| margin-bottom: 30px; | |
| padding: 20px 0; | |
| } | |
| .header h1 { | |
| color: var(--primary-color); | |
| font-weight: bold; | |
| margin: 0; | |
| font-size: 2.5rem; | |
| } | |
| .form-section { | |
| background: white; | |
| padding: 25px; | |
| border-radius: var(--border-radius); | |
| box-shadow: var(--card-shadow); | |
| margin-bottom: 30px; | |
| } | |
| .chart-container { | |
| background: white; | |
| padding: 25px; | |
| border-radius: var(--border-radius); | |
| box-shadow: var(--card-shadow); | |
| margin-bottom: 30px; | |
| } | |
| .insights-container { | |
| background: white; | |
| padding: 25px; | |
| border-radius: var(--border-radius); | |
| box-shadow: var(--card-shadow); | |
| margin-bottom: 30px; | |
| border-left: 5px solid var(--primary-color); | |
| } | |
| .insights-container h3 { | |
| color: var(--primary-color); | |
| margin-bottom: 20px; | |
| } | |
| .loading { | |
| display: none; | |
| text-align: center; | |
| padding: 20px; | |
| background: rgba(255, 255, 255, 0.9); | |
| position: fixed; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| border-radius: var(--border-radius); | |
| box-shadow: var(--card-shadow); | |
| z-index: 1000; | |
| } | |
| .btn-custom { | |
| background-color: var(--primary-color); | |
| color: white; | |
| border: none; | |
| padding: 8px 16px; | |
| border-radius: 4px; | |
| transition: background-color 0.3s ease; | |
| } | |
| .btn-custom:hover { | |
| background-color: var(--secondary-color); | |
| color: white; | |
| } | |
| .form-control { | |
| border-radius: 4px; | |
| border: 1px solid #ddd; | |
| padding: 8px 12px; | |
| height: auto; | |
| } | |
| .form-control:focus { | |
| border-color: var(--primary-color); | |
| box-shadow: 0 0 0 0.2rem rgba(76, 175, 80, 0.25); | |
| } | |
| label { | |
| font-weight: 500; | |
| margin-bottom: 8px; | |
| color: var(--text-color); | |
| } | |
| #barChart, #lineChart, #boxChart { | |
| width: 100%; | |
| margin-bottom: 20px; | |
| } | |
| #aiInsights { | |
| line-height: 1.8; | |
| font-size: 1.1rem; | |
| } | |
| .alert { | |
| border-radius: var(--border-radius); | |
| padding: 15px 20px; | |
| margin-bottom: 20px; | |
| } | |
| .spinner-border { | |
| width: 3rem; | |
| height: 3rem; | |
| color: var(--primary-color); | |
| } | |
| #marketData { | |
| height: 600px; | |
| overflow-y: scroll; | |
| } | |
| .table-responsive{ | |
| height: 600px; | |
| } | |
| .insights-header { | |
| background: #4CAF50; | |
| color: white; | |
| padding: 15px 20px; | |
| border-radius: 8px 8px 0 0; | |
| margin: -25px -25px 20px -25px; | |
| } | |
| .insights-header h3 { | |
| margin: 0; | |
| color: white; | |
| } | |
| .insight-section { | |
| background: #f8f9fa; | |
| border-radius: 8px; | |
| padding: 20px; | |
| margin-bottom: 20px; | |
| border-left: 4px solid #4CAF50; | |
| } | |
| .insight-section h4 { | |
| color: #2E7D32; | |
| margin-bottom: 15px; | |
| font-size: 1.2rem; | |
| font-weight: bold; | |
| } | |
| .insight-card { | |
| background: white; | |
| border-radius: 6px; | |
| padding: 15px; | |
| margin-bottom: 15px; | |
| box-shadow: 0 1px 3px rgba(0,0,0,0.1); | |
| } | |
| .insight-card h5 { | |
| color: #1B5E20; | |
| margin-bottom: 10px; | |
| font-size: 1.1rem; | |
| } | |
| .insight-list { | |
| list-style: none; | |
| padding-left: 0; | |
| margin-bottom: 0; | |
| } | |
| .insight-list li { | |
| position: relative; | |
| padding-left: 20px; | |
| margin-bottom: 8px; | |
| line-height: 1.5; | |
| } | |
| .insight-list li:before { | |
| content: "•"; | |
| color: #4CAF50; | |
| font-size: 1.2em; | |
| position: absolute; | |
| left: 0; | |
| top: -2px; | |
| } | |
| .price-highlight { | |
| color: #2E7D32; | |
| font-weight: bold; | |
| } | |
| .percentage-up { | |
| color: #2E7D32; | |
| font-weight: bold; | |
| } | |
| .percentage-down { | |
| color: #c62828; | |
| font-weight: bold; | |
| } | |
| .action-box { | |
| background: #E8F5E9; | |
| border-radius: 6px; | |
| padding: 15px; | |
| margin-top: 20px; | |
| border: 1px dashed #4CAF50; | |
| } | |
| .action-box h5 { | |
| color: #2E7D32; | |
| margin-bottom: 10px; | |
| font-size: 1.1rem; | |
| } | |
| .action-list { | |
| list-style: none; | |
| padding-left: 0; | |
| margin-bottom: 0; | |
| } | |
| .action-list li { | |
| position: relative; | |
| padding-left: 25px; | |
| margin-bottom: 8px; | |
| line-height: 1.5; | |
| } | |
| .action-list li:before { | |
| content: "✓"; | |
| color: #4CAF50; | |
| position: absolute; | |
| left: 0; | |
| font-weight: bold; | |
| } | |
| @media (max-width: 768px) { | |
| .insights-container { | |
| padding: 15px; | |
| } | |
| .insights-header { | |
| padding: 12px 15px; | |
| margin: -15px -15px 15px -15px; | |
| } | |
| .insight-section { | |
| padding: 15px; | |
| } | |
| } | |
| @media (max-width: 768px) { | |
| .container { | |
| padding: 10px; | |
| } | |
| .header h1 { | |
| font-size: 2rem; | |
| } | |
| .form-row { | |
| flex-direction: column; | |
| } | |
| .form-group { | |
| margin-bottom: 15px; | |
| } | |
| .btn-custom { | |
| width: 100%; | |
| } | |
| .insights-container { | |
| padding: 15px; | |
| } | |
| #aiInsights { | |
| font-size: 1rem; | |
| } | |
| } | |
| .language-selector { | |
| margin-top: 10px; | |
| } | |
| .lang-btn { | |
| font-size: 0.85rem; | |
| padding: 0.25rem 0.5rem; | |
| margin: 0 2px; | |
| border-radius: 4px; | |
| } | |
| .lang-btn.active { | |
| background-color: #4CAF50; | |
| color: white; | |
| } | |
| .current-language-indicator { | |
| font-size: 0.8rem; | |
| color: #555; | |
| margin: 5px 0 15px 0; | |
| } | |
| /* For mobile responsiveness */ | |
| @media (max-width: 768px) { | |
| .language-selector .btn-group { | |
| display: flex; | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| } | |
| .lang-btn { | |
| margin: 2px; | |
| flex: 0 0 auto; | |
| } | |
| } | |
| select { | |
| max-height: 200px; | |
| overflow-y: auto; | |
| } | |
| .audio-player-container { | |
| background: #e8f5e9; | |
| padding: 12px; | |
| border-radius: 8px; | |
| margin: 10px 0 0 20px; | |
| display: inline-block; | |
| vertical-align: middle; | |
| } | |
| .audio-player-container h4 { | |
| color: #2E7D32; | |
| margin: 0 0 8px 0; | |
| font-size: 0.9rem; | |
| font-weight: bold; | |
| } | |
| .audio-player-container audio { | |
| height: 35px; | |
| vertical-align: middle; | |
| } | |
| #playAudioBtn { | |
| background-color: #4CAF50; | |
| color: white; | |
| border: none; | |
| margin-left: 5px; | |
| font-size: 0.85em; | |
| } | |
| #playAudioBtn:hover { | |
| background-color: #45a049; | |
| } | |
| @media (max-width: 768px) { | |
| .insights-header { | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .audio-player-container { | |
| margin: 10px 0 0 0; | |
| width: 100%; | |
| } | |
| .audio-player-container audio { | |
| width: 100%; | |
| } | |
| #playAudioBtn { | |
| display: block; | |
| width: 100%; | |
| margin: 5px 0 0 0; | |
| } | |
| } | |
| /* Add FontAwesome for play/pause icons */ | |
| .fa { | |
| display: inline-block; | |
| font: normal normal normal 14px/1 FontAwesome; | |
| font-size: inherit; | |
| text-rendering: auto; | |
| -webkit-font-smoothing: antialiased; | |
| -moz-osx-font-smoothing: grayscale; | |
| } | |
| .fa-play:before { | |
| content: "\f04b"; | |
| } | |
| .fa-pause:before { | |
| content: "\f04c"; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <div class="header"> | |
| <h1>Crop Market Analysis</h1> | |
| </div> | |
| <div class="form-section"> | |
| <form id="filterForm"> | |
| <div class="form-row"> | |
| <div class="form-group col-md-3"> | |
| <label for="state">State</label> | |
| <select class="form-control" id="state" name="state"> | |
| <option value="">Select State</option> | |
| {% for state in states %} | |
| <option value="{{ state }}">{{ state }}</option> | |
| {% endfor %} | |
| </select> | |
| </div> | |
| <div class="form-group col-md-3"> | |
| <label for="district">District</label> | |
| <select class="form-control" id="district" name="district" disabled> | |
| <option value="">Select District</option> | |
| </select> | |
| </div> | |
| <div class="form-group col-md-3"> | |
| <label for="market">Market</label> | |
| <select class="form-control" id="market" name="market" disabled> | |
| <option value="">Select Market</option> | |
| </select> | |
| </div> | |
| <div class="form-group col-md-3"> | |
| <label for="commodity">Commodity</label> | |
| <select class="form-control" id="commodity" name="commodity" disabled> | |
| <option value="">Select Commodity</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="language-selector"> | |
| <div class="card"> | |
| <div class="card-body"> | |
| <h5 class="card-title">Select Language for AI Insights</h5> | |
| <div class="btn-group" role="group" aria-label="Language selection"> | |
| <button type="button" class="btn btn-sm lang-btn active" data-lang="English">English</button> | |
| <button type="button" class="btn btn-sm lang-btn" data-lang="Hindi">हिन्दी</button> | |
| <button type="button" class="btn btn-sm lang-btn" data-lang="Tamil">தமிழ்</button> | |
| <button type="button" class="btn btn-sm lang-btn" data-lang="Telugu">తెలుగు</button> | |
| <button type="button" class="btn btn-sm lang-btn" data-lang="Marathi">मराठी</button> | |
| <button type="button" class="btn btn-sm lang-btn" data-lang="Bengali">বাংলা</button> | |
| <button type="button" class="btn btn-sm lang-btn" data-lang="Gujarati">ગુજરાતી</button> | |
| <button type="button" class="btn btn-sm lang-btn" data-lang="Kannada">ಕನ್ನಡ</button> | |
| <button type="button" class="btn btn-sm lang-btn" data-lang="Malayalam">മലയാളം</button> | |
| <button type="button" class="btn btn-sm lang-btn" data-lang="Punjabi">ਪੰਜਾਬੀ</button> | |
| </div> | |
| <div class="current-language-indicator mt-2"> | |
| Current language: <span id="currentLanguage">English</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </form> | |
| </div> | |
| <div class="loading" id="loadingIndicator"> | |
| <div class="spinner-border" role="status"> | |
| <span class="sr-only">Loading...</span> | |
| </div> | |
| </div> | |
| <div class="chart-container"> | |
| <div id="barChart"></div> | |
| <div id="lineChart"></div> | |
| <div id="boxChart"></div> | |
| </div> | |
| <div class="market-data-container"> | |
| <div class="row"> | |
| <div class="col-md-12 mb-4"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h4>Market Statistics</h4> | |
| </div> | |
| <div class="card-body"> | |
| <div class="row"> | |
| <div class="col-md-3"> | |
| <div class="stat-item"> | |
| <h6>Total Commodities</h6> | |
| <span id="totalCommodities"></span> | |
| </div> | |
| </div> | |
| <div class="col-md-3"> | |
| <div class="stat-item"> | |
| <h6>Average Price</h6> | |
| <span id="avgPrice"></span> | |
| </div> | |
| </div> | |
| <div class="col-md-3"> | |
| <div class="stat-item"> | |
| <h6>Price Range</h6> | |
| <span id="priceRange"></span> | |
| </div> | |
| </div> | |
| <div class="col-md-3"> | |
| <div class="stat-item"> | |
| <h6>Total Markets</h6> | |
| <span id="totalMarkets"></span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="row"> | |
| <div class="col-md-6 mb-4"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h4>Top 5 Cheapest Crops</h4> | |
| </div> | |
| <div class="card-body" id="cheapestCrops"> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="col-md-6 mb-4"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h4>Top 5 Costliest Crops</h4> | |
| </div> | |
| <div class="card-body" id="costliestCrops"> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="card mb-4"> | |
| <div class="card-header"> | |
| <h4>Market Data</h4> | |
| </div> | |
| <div class="card-body" id="marketData"> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="insights-container"> | |
| <div id="aiInsights"></div> | |
| </div> | |
| </div> | |
| <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> | |
| <script> | |
| // Add this to your JavaScript | |
| function updateAudioPlayer(audioPath) { | |
| if (audioPath) { | |
| $('#audioPlayerContainer').show(); | |
| $('#insightsAudio').attr('src', audioPath); | |
| } else { | |
| $('#audioPlayerContainer').hide(); | |
| } | |
| } | |
| function showLoading() { | |
| $('#loadingIndicator').show(); | |
| } | |
| function hideLoading() { | |
| $('#loadingIndicator').hide(); | |
| } | |
| function enableSelect(selectId) { | |
| $(`#${selectId}`).prop('disabled', false); | |
| } | |
| function disableSelect(selectId) { | |
| $(`#${selectId}`).prop('disabled', true); | |
| } | |
| function updateContent() { | |
| showLoading(); | |
| const formData = new FormData($('#filterForm')[0]); | |
| $.ajax({ | |
| url: '/filter_data', | |
| method: 'POST', | |
| data: formData, | |
| processData: false, | |
| contentType: false, | |
| success: function(response) { | |
| if (response.success) { | |
| if (response.plots.bar) $('#barChart').html(response.plots.bar); | |
| if (response.plots.line) $('#lineChart').html(response.plots.line); | |
| if (response.plots.box) $('#boxChart').html(response.plots.box); | |
| $('#totalCommodities').text(response.market_stats.total_commodities); | |
| $('#avgPrice').text(response.market_stats.avg_modal_price); | |
| $('#priceRange').text(response.market_stats.price_range); | |
| $('#totalMarkets').text(response.market_stats.total_markets); | |
| $('#marketData').html(response.market_html); | |
| $('#cheapestCrops').html(response.cheapest_html); | |
| $('#costliestCrops').html(response.costliest_html); | |
| if (response.hasStateDistrict) { | |
| $('.insights-container').show(); | |
| $('#aiInsights').html(response.insights); | |
| } else { | |
| $('.insights-container').hide(); | |
| $('#aiInsights').html(''); | |
| } | |
| } else { | |
| alert('Please select both state and district to view analysis'); | |
| } | |
| hideLoading(); | |
| }, | |
| error: function() { | |
| alert('Error loading data'); | |
| hideLoading(); | |
| } | |
| }); | |
| } | |
| $('#state').change(function() { | |
| const state = $(this).val(); | |
| $('#district, #market, #commodity').html('<option value="">Select</option>').prop('disabled', true); | |
| if (state) { | |
| showLoading(); | |
| $.post('/get_districts', { state: state }, function(districts) { | |
| $('#district').html('<option value="">Select District</option>'); | |
| districts.forEach(district => { | |
| $('#district').append(`<option value="${district}">${district}</option>`); | |
| }); | |
| enableSelect('district'); | |
| hideLoading(); | |
| }); | |
| } | |
| updateContent(); | |
| }); | |
| $('#district').change(function() { | |
| const district = $(this).val(); | |
| $('#market, #commodity').html('<option value="">Select</option>').prop('disabled', true); | |
| if (district) { | |
| showLoading(); | |
| $.post('/get_markets', { district: district }, function(markets) { | |
| $('#market').html('<option value="">Select Market</option>'); | |
| markets.forEach(market => { | |
| $('#market').append(`<option value="${market}">${market}</option>`); | |
| }); | |
| enableSelect('market'); | |
| hideLoading(); | |
| }); | |
| } | |
| updateContent(); | |
| }); | |
| $('#market').change(function() { | |
| const market = $(this).val(); | |
| $('#commodity').html('<option value="">Select</option>').prop('disabled', true); | |
| if (market) { | |
| showLoading(); | |
| $.post('/get_commodities', { market: market }, function(commodities) { | |
| $('#commodity').html('<option value="">Select Commodity</option>'); | |
| commodities.forEach(commodity => { | |
| $('#commodity').append(`<option value="${commodity}">${commodity}</option>`); | |
| }); | |
| enableSelect('commodity'); | |
| hideLoading(); | |
| }); | |
| } | |
| updateContent(); | |
| }); | |
| $('#commodity').change(function() { | |
| updateContent(); | |
| }); | |
| $(document).ready(function() { | |
| $('.insights-container').hide(); | |
| updateContent(); | |
| }); | |
| // Language handling | |
| let currentLanguage = "English"; | |
| $('.lang-btn').click(function() { | |
| $('.lang-btn').removeClass('active'); | |
| $(this).addClass('active'); | |
| currentLanguage = $(this).data('lang'); | |
| $('#currentLanguage').text(currentLanguage); | |
| // If state and district are selected, update the content to reflect the new language | |
| if ($('#state').val() && $('#district').val()) { | |
| updateContent(); | |
| } | |
| }); | |
| // Modify the updateContent function to include language | |
| function updateContent() { | |
| showLoading(); | |
| const formData = new FormData($('#filterForm')[0]); | |
| // Add language to form data | |
| formData.append('language', currentLanguage); | |
| $.ajax({ | |
| url: '/filter_data', | |
| method: 'POST', | |
| data: formData, | |
| processData: false, | |
| contentType: false, | |
| success: function(response) { | |
| if (response.success) { | |
| if (response.plots.bar) $('#barChart').html(response.plots.bar); | |
| if (response.plots.line) $('#lineChart').html(response.plots.line); | |
| if (response.plots.box) $('#boxChart').html(response.plots.box); | |
| $('#totalCommodities').text(response.market_stats.total_commodities); | |
| $('#avgPrice').text(response.market_stats.avg_modal_price); | |
| $('#priceRange').text(response.market_stats.price_range); | |
| $('#totalMarkets').text(response.market_stats.total_markets); | |
| $('#marketData').html(response.market_html); | |
| $('#cheapestCrops').html(response.cheapest_html); | |
| $('#costliestCrops').html(response.costliest_html); | |
| if (response.hasStateDistrict) { | |
| $('.insights-container').show(); | |
| $('#aiInsights').html(response.insights); | |
| } else { | |
| $('.insights-container').hide(); | |
| $('#aiInsights').html(''); | |
| } | |
| } else { | |
| alert('Please select both state and district to view analysis'); | |
| } | |
| hideLoading(); | |
| }, | |
| error: function() { | |
| alert('Error loading data'); | |
| hideLoading(); | |
| } | |
| }); | |
| } | |
| // Add this in the <head> section after the jQuery import | |
| $(document).on('click', '#playAudioBtn', function() { | |
| const audioPlayer = document.getElementById('insightsAudio'); | |
| if (audioPlayer) { | |
| if (audioPlayer.paused) { | |
| audioPlayer.play(); | |
| $(this).html('<i class="fa fa-pause"></i> Pause Audio'); | |
| } else { | |
| audioPlayer.pause(); | |
| $(this).html('<i class="fa fa-play"></i> Play Audio'); | |
| } | |
| } | |
| }); | |
| // Reset play button text when audio ends | |
| $(document).on('ended', '#insightsAudio', function() { | |
| $('#playAudioBtn').html('<i class="fa fa-play"></i> Play Audio'); | |
| }); | |
| </script> | |
| <script src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"></script> | |
| </body> | |
| </html> | |