Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Farm Details</title> | |
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> | |
<style> | |
#map { | |
height: 400px; | |
width: 100%; | |
border-radius: 8px; | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
margin-bottom: 20px; | |
} | |
.card { | |
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
margin-bottom: 20px; | |
} | |
.weather-icon { | |
width: 64px; | |
height: 64px; | |
} | |
</style> | |
</head> | |
<body class="bg-light"> | |
<div class="container py-5"> | |
<div class="d-flex justify-content-between align-items-center mb-4"> | |
<h1>Farm Details</h1> | |
<div> | |
<a href="/farms" class="btn btn-secondary me-2">Back to Farms</a> | |
<a href="/edit_farm/{{ farm.id }}" class="btn btn-primary">Edit Farm</a> | |
<button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#deleteFarmModal"> | |
Delete Farm | |
</button> | |
</div> | |
</div> | |
<div class="row"> | |
<!-- Farm Information --> | |
<div class="col-lg-6"> | |
<div class="card"> | |
<div class="card-header bg-primary text-white"> | |
<h3 class="card-title">Farm Information</h3> | |
</div> | |
<div class="card-body"> | |
<table class="table table-striped"> | |
<tr> | |
<th>Farmer Name</th> | |
<td>{{ farm.owner.name }}</td> | |
</tr> | |
<tr> | |
<th>Contact</th> | |
<td>{{ farm.owner.contact_number }}</td> | |
</tr> | |
<tr> | |
<th>Address</th> | |
<td>{{ farm.owner.address }}</td> | |
</tr> | |
<tr> | |
<th>Total Farm Area</th> | |
<td>{{ farm.farm_size|round(2) if farm.farm_size else 'Not specified' }} acres</td> | |
</tr> | |
<tr> | |
<th>Registration Date</th> | |
<td>{{ farm.created_at.strftime('%d %b %Y') }}</td> | |
</tr> | |
</table> | |
</div> | |
</div> | |
<!-- Crops Information --> | |
<div class="card"> | |
<div class="card-header bg-success text-white"> | |
<h3 class="card-title">Crops Information</h3> | |
</div> | |
<div class="card-body"> | |
{% if crops_data and crops_data|length > 0 %} | |
<table class="table table-bordered"> | |
<thead> | |
<tr> | |
<th>Crop Name</th> | |
<th>Area (acres)</th> | |
<th>Sowing Month</th> | |
</tr> | |
</thead> | |
<tbody> | |
{% for crop in crops_data %} | |
<tr> | |
<td>{{ crop.name }}</td> | |
<td>{{ crop.area }}</td> | |
<td>{{ crop.sowing_month }}</td> | |
</tr> | |
{% endfor %} | |
</tbody> | |
</table> | |
{% else %} | |
<p class="text-muted">No crop details available.</p> | |
{% endif %} | |
</div> | |
</div> | |
</div> | |
<!-- Map and Weather --> | |
<div class="col-lg-6"> | |
<div class="card"> | |
<div class="card-header bg-info text-white"> | |
<h3 class="card-title">Farm Location</h3> | |
</div> | |
<div class="card-body"> | |
<div id="map"></div> | |
</div> | |
</div> | |
<div class="card"> | |
<div class="card-header bg-warning"> | |
<h3 class="card-title">Current Weather</h3> | |
</div> | |
<div class="card-body"> | |
{% if weather and not weather.get('error', False) %} | |
<div class="row align-items-center"> | |
<div class="col-md-6"> | |
<h4>{{ weather.name }}</h4> | |
<div class="d-flex align-items-center"> | |
<img src="http://openweathermap.org/img/wn/{{ weather.weather[0].icon }}@2x.png" alt="{{ weather.weather[0].description }}" class="weather-icon me-3"> | |
<div> | |
<h2>{{ weather.main.temp|round(1) }}°C</h2> | |
<p class="mb-0">{{ weather.weather[0].description|capitalize }}</p> | |
</div> | |
</div> | |
</div> | |
<div class="col-md-6"> | |
<ul class="list-unstyled"> | |
<li><strong>Humidity:</strong> {{ weather.main.humidity }}%</li> | |
<li><strong>Wind:</strong> {{ weather.wind.speed }} m/s</li> | |
{% if weather.main.get('feels_like') %} | |
<li><strong>Feels like:</strong> {{ weather.main.feels_like|round(1) }}°C</li> | |
{% endif %} | |
</ul> | |
</div> | |
</div> | |
{% else %} | |
<p>Weather data unavailable.</p> | |
{% endif %} | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Agriculture News Section --> | |
{% if news and news|length > 0 %} | |
<div class="card mt-4"> | |
<div class="card-header bg-secondary text-white"> | |
<h3 class="card-title">Agriculture News</h3> | |
</div> | |
<div class="card-body"> | |
<div class="row"> | |
{% for article in news %} | |
<div class="col-md-4 mb-3"> | |
<div class="card h-100"> | |
{% if article.urlToImage %} | |
<img src="{{ article.urlToImage }}" class="card-img-top" alt="{{ article.title }}"> | |
{% endif %} | |
<div class="card-body"> | |
<h5 class="card-title">{{ article.title }}</h5> | |
<p class="card-text small">{{ article.description|truncate(100) }}</p> | |
</div> | |
<div class="card-footer"> | |
<a href="{{ article.url }}" target="_blank" class="btn btn-sm btn-primary">Read More</a> | |
</div> | |
</div> | |
</div> | |
{% endfor %} | |
</div> | |
</div> | |
</div> | |
{% endif %} | |
</div> | |
<!-- Delete Farm Modal --> | |
<div class="modal fade" id="deleteFarmModal" tabindex="-1" aria-hidden="true"> | |
<div class="modal-dialog"> | |
<div class="modal-content"> | |
<div class="modal-header bg-danger text-white"> | |
<h5 class="modal-title">Confirm Deletion</h5> | |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> | |
</div> | |
<div class="modal-body"> | |
<p>Are you sure you want to delete this farm? This action cannot be undone.</p> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> | |
<form action="/delete_farm/{{ farm.id }}" method="POST"> | |
<button type="submit" class="btn btn-danger">Delete Farm</button> | |
</form> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script> | |
<script> | |
let map; | |
let farmBoundary; | |
function initMap() { | |
// Center the map on farm coordinates | |
const farmCenter = {lat: {{ farm.latitude }}, lng: {{ farm.longitude }}}; | |
map = new google.maps.Map(document.getElementById('map'), { | |
zoom: 15, | |
center: farmCenter, | |
mapTypeId: 'satellite' | |
}); | |
// Add marker for farm center | |
const marker = new google.maps.Marker({ | |
position: farmCenter, | |
map: map, | |
title: "{{ farm.farm_name }}" | |
}); | |
// Add farm boundary if coordinates exist | |
{% if farm.field_coordinates %} | |
try { | |
const coordinates = JSON.parse('{{ farm.field_coordinates|safe }}'); | |
const farmBoundaryPath = coordinates.map(coord => ({lat: coord.lat, lng: coord.lng})); | |
farmBoundary = new google.maps.Polygon({ | |
paths: farmBoundaryPath, | |
strokeColor: '#4CAF50', | |
strokeOpacity: 0.8, | |
strokeWeight: 3, | |
fillColor: '#4CAF50', | |
fillOpacity: 0.35 | |
}); | |
farmBoundary.setMap(map); | |
// Adjust bounds to fit the farm boundary | |
const bounds = new google.maps.LatLngBounds(); | |
farmBoundaryPath.forEach(coord => bounds.extend(coord)); | |
map.fitBounds(bounds); | |
} catch (e) { | |
console.error("Error parsing farm boundary coordinates:", e); | |
} | |
{% endif %} | |
} | |
</script> | |
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBvVLjWmCja331H8SuIZ4UlJdZytuYkC6Y&callback=initMap"></script> | |
</body> | |
</html> | |