mirror of
https://github.com/furyhawk/home_stack.git
synced 2026-07-21 10:16:47 +00:00
refactor: Update makefile to replace 'docker-completed.yml' with 'docker-compose.yml' for consistency
This commit is contained in:
@@ -1,194 +0,0 @@
|
||||
import React from "react"
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Container,
|
||||
Flex,
|
||||
Heading,
|
||||
Text,
|
||||
if (error) {
|
||||
return (
|
||||
<Container maxW="full">
|
||||
<Heading size="lg" pt={12} mb={6}>
|
||||
Singapore Weather Forecast
|
||||
</Heading>
|
||||
<Box bg="whiteAlpha.200" p={6} borderRadius="md" shadow="md">
|
||||
<WeatherErrorDisplay retry={handleRefresh} error={error} />
|
||||
</Box>
|
||||
</Container>
|
||||
)
|
||||
}kra-ui/react"
|
||||
import { useQuery } from "@tanstack/react-query"
|
||||
import { createFileRoute } from "@tanstack/react-router"
|
||||
import { useState } from "react"
|
||||
import { FiRefreshCw } from "react-icons/fi"
|
||||
|
||||
import { WeatherService } from "@/client"
|
||||
import WeatherErrorDisplay from "@/components/Weather/WeatherErrorDisplay"
|
||||
import WeatherLoadingAnimation from "@/components/Weather/WeatherLoadingAnimation"
|
||||
import WeatherForecast from "@/components/Weather/WeatherForecast"
|
||||
import useCustomToast from "@/hooks/useCustomToast"
|
||||
|
||||
export const Route = createFileRoute("/_layout/weather")({
|
||||
component: Weather,
|
||||
})
|
||||
|
||||
function Weather() {
|
||||
const { showSuccessToast } = useCustomToast()
|
||||
const [selectedArea, setSelectedArea] = useState<string>("All Areas")
|
||||
|
||||
const {
|
||||
data,
|
||||
isLoading,
|
||||
error,
|
||||
refetch,
|
||||
dataUpdatedAt
|
||||
} = useQuery({
|
||||
queryKey: ["weather", "two-hour-forecast"],
|
||||
queryFn: () => WeatherService.getTwoHourForecast(),
|
||||
refetchInterval: 1000 * 60 * 30, // Refetch every 30 minutes
|
||||
staleTime: 1000 * 60 * 15, // Consider data stale after 15 minutes
|
||||
})
|
||||
|
||||
// Format date for display
|
||||
const formatUpdateTime = (timestamp: string) => {
|
||||
const date = new Date(timestamp)
|
||||
return date.toLocaleString([], {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
})
|
||||
}
|
||||
|
||||
// Format the time when data was last fetched
|
||||
const formatLastFetchedTime = (timestamp: number) => {
|
||||
const date = new Date(timestamp)
|
||||
return date.toLocaleString([], {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
})
|
||||
}
|
||||
|
||||
// Handle manual refresh
|
||||
const handleRefresh = () => {
|
||||
refetch()
|
||||
showSuccessToast("Refreshing weather data")
|
||||
}
|
||||
|
||||
// Filter forecasts by area if selected
|
||||
const getFilteredForecasts = () => {
|
||||
if (!data?.data?.items || data.data.items.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
const forecasts = data.data.items[0].forecasts
|
||||
if (selectedArea === "All Areas") {
|
||||
return forecasts
|
||||
}
|
||||
|
||||
return forecasts.filter(forecast => forecast.area === selectedArea)
|
||||
}
|
||||
|
||||
// Get unique areas for the dropdown
|
||||
const getUniqueAreas = () => {
|
||||
if (!data?.data?.items || data.data.items.length === 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
const areas = data.data.items[0].forecasts.map(f => f.area)
|
||||
return ["All Areas", ...areas].sort()
|
||||
} if (error) {
|
||||
return (
|
||||
<Container maxW="full">
|
||||
<Heading size="lg" pt={12} mb={6}>
|
||||
Singapore Weather Forecast
|
||||
</Heading>
|
||||
<Box bg="whiteAlpha.200" p={6} borderRadius="md" shadow="md">
|
||||
<WeatherErrorDisplay retry={handleRefresh} error={error} />
|
||||
</Box>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Container maxW="full">
|
||||
<Heading size="lg" pt={12} mb={6}>
|
||||
Singapore Weather Forecast
|
||||
</Heading>
|
||||
|
||||
<Box bg="whiteAlpha.200" p={6} borderRadius="md" shadow="md">
|
||||
{isLoading ? (
|
||||
<WeatherLoadingAnimation />
|
||||
) : data?.data?.items && data.data.items.length > 0 ? (
|
||||
<>
|
||||
<Flex
|
||||
direction={{ base: "column", md: "row" }}
|
||||
justifyContent="space-between"
|
||||
alignItems={{ base: "flex-start", md: "center" }}
|
||||
mb={6}
|
||||
gap={4}
|
||||
>
|
||||
<Box>
|
||||
<Text fontSize="sm" color="gray.500">
|
||||
Last Updated:{" "}
|
||||
{formatUpdateTime(data.data.items[0].update_timestamp)}
|
||||
</Text>
|
||||
<Text fontSize="xs" color="gray.500">
|
||||
Data fetched at: {formatLastFetchedTime(dataUpdatedAt)}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
<Flex gap={4} alignItems="center">
|
||||
<select
|
||||
value={selectedArea}
|
||||
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => setSelectedArea(e.target.value)}
|
||||
style={{
|
||||
padding: '0.5rem',
|
||||
borderRadius: '0.375rem',
|
||||
minWidth: '200px',
|
||||
fontSize: '0.875rem'
|
||||
}}
|
||||
>
|
||||
{getUniqueAreas().map(area => (
|
||||
<option key={area} value={area}>{area}</option>
|
||||
))}
|
||||
</select>
|
||||
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={handleRefresh}
|
||||
>
|
||||
<Flex alignItems="center" gap={2}>
|
||||
<FiRefreshCw />
|
||||
<Text>Refresh</Text>
|
||||
</Flex>
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
|
||||
<WeatherForecast
|
||||
forecasts={getFilteredForecasts()}
|
||||
validPeriod={data.data.items[0].valid_period}
|
||||
areaMetadata={data.data.area_metadata || []}
|
||||
/>
|
||||
|
||||
<Text mt={6} fontSize="xs" color="gray.500">
|
||||
Data provided by NEA through data.gov.sg API
|
||||
</Text>
|
||||
</>
|
||||
) : (
|
||||
<Box textAlign="center" py={10}>
|
||||
<Text>No weather forecast data available at this time.</Text>
|
||||
<Button mt={4} onClick={handleRefresh}>
|
||||
Try Again
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
@@ -19,20 +19,20 @@ network:
|
||||
@echo "Traefik network ready."
|
||||
|
||||
up: network
|
||||
podman compose --env-file $(ENV_FILE) -f docker-completed.yml -f docker-compose.override.yml up -d
|
||||
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d
|
||||
|
||||
down:
|
||||
podman compose --env-file $(ENV_FILE) -f docker-completed.yml -f docker-compose.override.yml down
|
||||
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down
|
||||
@echo "Containers stopped. Use 'make up' to start them again."
|
||||
|
||||
build:
|
||||
DOCKER_BUILDKIT=0 podman compose --env-file $(ENV_FILE) -f docker-completed.yml -f docker-compose.override.yml build --no-cache
|
||||
DOCKER_BUILDKIT=0 podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml build --no-cache
|
||||
@echo "Containers built. Use 'make up' to start them."
|
||||
|
||||
restart: down build up
|
||||
|
||||
reset:
|
||||
podman compose --env-file $(ENV_FILE) -f docker-completed.yml -f docker-compose.override.yml down -v
|
||||
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down -v
|
||||
podman system prune -f
|
||||
podman volume prune -f
|
||||
podman network prune -f
|
||||
@@ -55,17 +55,17 @@ restore:
|
||||
podman volume rm $(DB_VOLUME) || true
|
||||
podman volume create --name $(DB_VOLUME)
|
||||
podman volume import $(DB_VOLUME) --input $(LATEST_BACKUP)
|
||||
podman compose --env-file $(ENV_FILE) -f docker-completed.yml -f docker-compose.override.yml up -d
|
||||
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml up -d
|
||||
@echo "Backup and restore completed."
|
||||
@echo "Please check the logs for any errors."
|
||||
@echo "Use 'make logs' to view the logs."
|
||||
|
||||
logs:
|
||||
podman compose --env-file $(ENV_FILE) -f docker-completed.yml -f docker-compose.override.yml logs
|
||||
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml logs
|
||||
@echo "Logs for all containers:"
|
||||
|
||||
clean:
|
||||
podman compose --env-file $(ENV_FILE) -f docker-completed.yml -f docker-compose.override.yml down
|
||||
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml down
|
||||
podman volume rm $(DB_VOLUME)
|
||||
@echo "Cleaned up all containers and volumes."
|
||||
|
||||
@@ -107,4 +107,4 @@ info:
|
||||
@echo "\n===== Podman Images ====="
|
||||
podman images
|
||||
@echo "\n===== Podman Compose Config ====="
|
||||
podman compose --env-file $(ENV_FILE) -f docker-completed.yml -f docker-compose.override.yml config
|
||||
podman compose --env-file $(ENV_FILE) -f docker-compose.yml -f docker-compose.override.yml config
|
||||
|
||||
Reference in New Issue
Block a user