first commit
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"tankstopp/internal/models"
|
||||
"tankstopp/internal/views/pages"
|
||||
)
|
||||
|
||||
// HomeHandler serves the main dashboard page
|
||||
func (h *Handler) HomeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
userID, username := h.getCurrentUser(r)
|
||||
if userID == 0 {
|
||||
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the user object
|
||||
user, err := h.db.GetUserByID(userID)
|
||||
if err != nil {
|
||||
log.Printf("Error getting user: %v", err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Get fuel stops for the user
|
||||
stops, err := h.db.GetFuelStops(userID)
|
||||
if err != nil {
|
||||
log.Printf("Error getting fuel stops: %v", err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Get fuel stop statistics
|
||||
stats, err := h.db.GetFuelStopStats(userID)
|
||||
if err != nil {
|
||||
log.Printf("Error getting fuel stop stats: %v", err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Get vehicles for the user
|
||||
vehicles, err := h.db.GetVehicles(userID)
|
||||
if err != nil {
|
||||
log.Printf("Error getting vehicles: %v", err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate dashboard statistics
|
||||
totalStops := len(stops)
|
||||
totalCost := stats.TotalSpent
|
||||
|
||||
// Calculate detailed consumption statistics
|
||||
avgConsumption, _, _ := h.calculateConsumptionStats(stops)
|
||||
if avgConsumption == 0 {
|
||||
avgConsumption = stats.AverageConsumption // Fallback to basic stats
|
||||
}
|
||||
|
||||
var lastFillUp *models.FuelStop
|
||||
if len(stops) > 0 {
|
||||
lastFillUp = &stops[0]
|
||||
}
|
||||
|
||||
// Render dashboard using templ
|
||||
component := pages.DashboardPage(user, username, stops, vehicles, totalStops, totalCost, avgConsumption, lastFillUp)
|
||||
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
err = component.Render(r.Context(), w)
|
||||
if err != nil {
|
||||
log.Printf("Error rendering template: %v", err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
// calculateConsumptionStats calculates consumption-related statistics
|
||||
func (h *Handler) calculateConsumptionStats(stops []models.FuelStop) (float64, float64, float64) {
|
||||
if len(stops) == 0 {
|
||||
return 0, 0, 0
|
||||
}
|
||||
|
||||
var totalLiters, totalKm float64
|
||||
var consumptionReadings []float64
|
||||
|
||||
for _, stop := range stops {
|
||||
totalLiters += stop.Liters
|
||||
|
||||
if stop.TripLength > 0 {
|
||||
totalKm += stop.TripLength
|
||||
|
||||
// Calculate consumption for this stop (L/100km)
|
||||
consumption := (stop.Liters / stop.TripLength) * 100
|
||||
if consumption > 0 && consumption < 50 { // Filter out unrealistic values
|
||||
consumptionReadings = append(consumptionReadings, consumption)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Average consumption from individual readings
|
||||
var avgConsumption float64
|
||||
if len(consumptionReadings) > 0 {
|
||||
var sum float64
|
||||
for _, consumption := range consumptionReadings {
|
||||
sum += consumption
|
||||
}
|
||||
avgConsumption = sum / float64(len(consumptionReadings))
|
||||
}
|
||||
|
||||
// Overall consumption from totals
|
||||
var overallConsumption float64
|
||||
if totalKm > 0 {
|
||||
overallConsumption = (totalLiters / totalKm) * 100
|
||||
}
|
||||
|
||||
return avgConsumption, overallConsumption, totalKm
|
||||
}
|
||||
|
||||
// calculateEfficiencyTrend calculates fuel efficiency trend over time
|
||||
func (h *Handler) calculateEfficiencyTrend(stops []models.FuelStop) string {
|
||||
if len(stops) < 2 {
|
||||
return "insufficient_data"
|
||||
}
|
||||
|
||||
// Get consumption for recent stops (last 5) vs older stops
|
||||
recentStops := stops[:min(5, len(stops))]
|
||||
olderStops := stops[min(5, len(stops)):]
|
||||
|
||||
recentAvg, _, _ := h.calculateConsumptionStats(recentStops)
|
||||
olderAvg, _, _ := h.calculateConsumptionStats(olderStops)
|
||||
|
||||
if recentAvg == 0 || olderAvg == 0 {
|
||||
return "insufficient_data"
|
||||
}
|
||||
|
||||
diff := recentAvg - olderAvg
|
||||
if diff < -0.5 {
|
||||
return "improving" // Lower consumption is better
|
||||
} else if diff > 0.5 {
|
||||
return "worsening"
|
||||
}
|
||||
return "stable"
|
||||
}
|
||||
|
||||
// min helper function
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
Reference in New Issue
Block a user