diff --git a/eco_project/backend/app.py b/eco_project/backend/app.py
index d589924..8173f03 100644
--- a/eco_project/backend/app.py
+++ b/eco_project/backend/app.py
@@ -728,6 +728,108 @@ def youtube_videos():
return jsonify({"error": str(e)}), 500
+@app.route('/api/unep_recycling')
+def unep_recycling():
+ # SDG Indicator 12.5.1: National recycling rate
+ # Series: EN_MWT_RCYR (Proportion of municipal waste recycled (%))
+ # UNEP is the custodian of this indicator.
+ url = "https://unstats.un.org/SDGAPI/v1/sdg/Series/Data?seriesCode=EN_MWT_RCYR&pageSize=1000"
+
+ try:
+ response = requests.get(url, timeout=10)
+ data = response.json()
+
+ if data and data.get('data'):
+ latest_data = {}
+ for entry in data['data']:
+ country = entry['geoAreaName']
+ year = entry['timePeriodStart']
+ value = entry['value']
+
+ if value is not None and (country not in latest_data or year > latest_data[country]['year']):
+ latest_data[country] = {
+ 'country': country,
+ 'year': int(year),
+ 'value': float(value)
+ }
+
+ # Top 10 countries
+ formatted_data = sorted(latest_data.values(), key=lambda x: x['value'], reverse=True)[:10]
+
+ logger.log_struct(
+ {
+ "message": "Successfully fetched UNEP recycling data.",
+ "component": "backend",
+ "endpoint": "/api/unep_recycling",
+ },
+ severity="INFO",
+ )
+ return jsonify(formatted_data)
+ else:
+ return jsonify({"error": "No data found"}), 404
+ except Exception as e:
+ logger.log_struct(
+ {
+ "message": f"Error fetching UNEP data: {e}",
+ "component": "backend",
+ "endpoint": "/api/unep_recycling",
+ },
+ severity="ERROR",
+ )
+ return jsonify({"error": str(e)}), 500
+
+
+@app.route('/api/unep_protected_areas')
+def unep_protected_areas():
+ # SDG Indicator 15.1.2: Protected areas
+ # Series: ER_PTD_TERR (Average proportion of Terrestrial KBAs covered by protected areas (%))
+ # UNEP is the custodian of this indicator.
+ url = "https://unstats.un.org/SDGAPI/v1/sdg/Series/Data?seriesCode=ER_PTD_TERR&pageSize=1000"
+
+ try:
+ response = requests.get(url, timeout=10)
+ data = response.json()
+
+ if data and data.get('data'):
+ latest_data = {}
+ for entry in data['data']:
+ country = entry['geoAreaName']
+ year = entry['timePeriodStart']
+ value = entry['value']
+
+ if value is not None and (country not in latest_data or year > latest_data[country]['year']):
+ latest_data[country] = {
+ 'country': country,
+ 'year': int(year),
+ 'value': float(value)
+ }
+
+ # Top 10 countries
+ formatted_data = sorted(latest_data.values(), key=lambda x: x['value'], reverse=True)[:10]
+
+ logger.log_struct(
+ {
+ "message": "Successfully fetched UNEP protected areas data.",
+ "component": "backend",
+ "endpoint": "/api/unep_protected_areas",
+ },
+ severity="INFO",
+ )
+ return jsonify(formatted_data)
+ else:
+ return jsonify({"error": "No data found"}), 404
+ except Exception as e:
+ logger.log_struct(
+ {
+ "message": f"Error fetching UNEP data: {e}",
+ "component": "backend",
+ "endpoint": "/api/unep_protected_areas",
+ },
+ severity="ERROR",
+ )
+ return jsonify({"error": str(e)}), 500
+
+
if __name__ == '__main__':
port = int(os.environ.get("PORT", 8080))
socketio.run(app, host='0.0.0.0', port=port, debug=False, allow_unsafe_werkzeug=True)
diff --git a/eco_project/backend/static/index.html b/eco_project/backend/static/index.html
index 6fa77b4..229b2f6 100644
--- a/eco_project/backend/static/index.html
+++ b/eco_project/backend/static/index.html
@@ -58,6 +58,7 @@
Community
Join the Chat
Watch Sports
Air Quality
+ UNEP Data
diff --git a/eco_project/backend/static/unep.css b/eco_project/backend/static/unep.css
new file mode 100644
index 0000000..bbb443a
--- /dev/null
+++ b/eco_project/backend/static/unep.css
@@ -0,0 +1,29 @@
+main {
+ padding: 20px;
+ max-width: 1000px;
+ margin: 0 auto;
+}
+
+section {
+ margin-bottom: 40px;
+ padding: 20px;
+ background-color: #f9f9f9;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+}
+
+h2 {
+ color: #2c3e50;
+ border-bottom: 2px solid #3498db;
+ padding-bottom: 10px;
+}
+
+canvas {
+ max-width: 100%;
+ height: auto;
+}
+
+#unep-intro {
+ background-color: #e8f4f8;
+ border-left: 5px solid #3498db;
+}
diff --git a/eco_project/backend/static/unep.html b/eco_project/backend/static/unep.html
new file mode 100644
index 0000000..98d5765
--- /dev/null
+++ b/eco_project/backend/static/unep.html
@@ -0,0 +1,41 @@
+
+
+
+
+
+ UNEP Data - Environment Protection
+
+
+
+
+
+
+ UN Environment Programme (UNEP) Data
+
+ Home
+
+
+
+
+ UNEP and the SDGs
+ The United Nations Environment Programme (UNEP) is the leading global authority on the environment. It is the custodian for many Sustainable Development Goal (SDG) indicators. Below is data for two key indicators custodianed by UNEP.
+
+
+
+ National Recycling Rate (SDG 12.5.1)
+ Proportion of municipal waste recycled (%) - Top 10 Countries
+
+
+
+
+ Protected Areas (SDG 15.1.2)
+ Average proportion of Terrestrial Key Biodiversity Areas (KBAs) covered by protected areas (%) - Top 10 Countries
+
+
+
+
+
+
+
diff --git a/eco_project/backend/static/unep.js b/eco_project/backend/static/unep.js
new file mode 100644
index 0000000..7ae5938
--- /dev/null
+++ b/eco_project/backend/static/unep.js
@@ -0,0 +1,56 @@
+fetchRecyclingData();
+fetchProtectedAreasData();
+
+function fetchRecyclingData() {
+ fetch('/api/unep_recycling')
+ .then(response => response.json())
+ .then(data => {
+ if (data.error) {
+ console.error('Error fetching recycling data:', data.error);
+ return;
+ }
+ renderChart('recyclingChart', data, 'Recycling Rate (%)', 'rgba(75, 192, 192, 0.2)', 'rgba(75, 192, 192, 1)');
+ })
+ .catch(error => console.error('Error:', error));
+}
+
+function fetchProtectedAreasData() {
+ fetch('/api/unep_protected_areas')
+ .then(response => response.json())
+ .then(data => {
+ if (data.error) {
+ console.error('Error fetching protected areas data:', data.error);
+ return;
+ }
+ renderChart('protectedAreasChart', data, 'Protected Area Coverage (%)', 'rgba(153, 102, 255, 0.2)', 'rgba(153, 102, 255, 1)');
+ })
+ .catch(error => console.error('Error:', error));
+}
+
+function renderChart(canvasId, data, label, bgColor, borderColor) {
+ const ctx = document.getElementById(canvasId).getContext('2d');
+ const labels = data.map(item => item.country);
+ const values = data.map(item => item.value);
+
+ new Chart(ctx, {
+ type: 'bar',
+ data: {
+ labels: labels,
+ datasets: [{
+ label: label,
+ data: values,
+ backgroundColor: bgColor,
+ borderColor: borderColor,
+ borderWidth: 1
+ }]
+ },
+ options: {
+ scales: {
+ y: {
+ beginAtZero: true,
+ max: 100
+ }
+ }
+ }
+ });
+}