164 lines
7.1 KiB
React
164 lines
7.1 KiB
React
import VdapApi from '../../hooks/useVdapApi.js';
|
|||
|
|
import {Flex, Spinner, Text, Button, Dialog, Box} from "@chakra-ui/react";
|
||
|
|
import * as url from "node:url"; // Adjust path as needed
|
||
|
|
import { useState } from 'react';
|
||
|
|
|
||
|
|
export default function IvansAlerts() {
|
||
|
|
console.log("IvansAlerts");
|
||
|
|
const [isSummaryOpen, setIsSummaryOpen] = useState(false);
|
||
|
|
const [isFileOpen, setIsFileOpen] = useState(false);
|
||
|
|
|
||
|
|
function SummaryDialog({ open, onOpenChange, item }) {
|
||
|
|
return (
|
||
|
|
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
||
|
|
<Dialog.Backdrop />
|
||
|
|
<Dialog.Positioner>
|
||
|
|
<Dialog.Content>
|
||
|
|
<Dialog.Header>
|
||
|
|
<Dialog.Title>Summary</Dialog.Title>
|
||
|
|
</Dialog.Header>
|
||
|
|
|
||
|
|
<Dialog.Body>
|
||
|
|
<Text>{item.summary}</Text>
|
||
|
|
</Dialog.Body>
|
||
|
|
|
||
|
|
<Dialog.Footer>
|
||
|
|
<Button variant="outline" onClick={() => onOpenChange({ open: false })}>
|
||
|
|
Close
|
||
|
|
</Button>
|
||
|
|
</Dialog.Footer>
|
||
|
|
<Dialog.CloseTrigger />
|
||
|
|
</Dialog.Content>
|
||
|
|
</Dialog.Positioner>
|
||
|
|
</Dialog.Root>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
function FileDialog({ open, onOpenChange, item, context }) {
|
||
|
|
return (
|
||
|
|
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
||
|
|
<Dialog.Backdrop />
|
||
|
|
<Dialog.Positioner>
|
||
|
|
<Dialog.Content>
|
||
|
|
<Dialog.Header>
|
||
|
|
<Flex width="100%" direction="row" align="center" justifyContent="space-between">
|
||
|
|
<Flex direction="column">
|
||
|
|
<Dialog.Title>{item.name ? item.name : 'PDF Attachment'}</Dialog.Title>
|
||
|
|
<Text color="gray.200">{context}</Text>
|
||
|
|
</Flex>
|
||
|
|
<Flex>
|
||
|
|
<Text bg="gray.800" p="1" borderRadius="sm">{item.type}</Text>
|
||
|
|
</Flex>
|
||
|
|
</Flex>
|
||
|
|
</Dialog.Header>
|
||
|
|
|
||
|
|
<Dialog.Body h="75vh" p={0}>
|
||
|
|
<Box bg="gray.900" w="100%" h="100%" display="flex" alignItems="center" justifyContent="center">
|
||
|
|
<object display="block" data={`${item.url}#view=FitH`} type="application/pdf">
|
||
|
|
<Flex height="100%" color="gray.400" p={4}>
|
||
|
|
<Text mb={2} color="fg.muted">Your browser cannot display this PDF directly.</Text>
|
||
|
|
<a href={item.url} target="_blank">
|
||
|
|
Download PDF
|
||
|
|
</a>
|
||
|
|
</Flex>
|
||
|
|
</object>
|
||
|
|
</Box>
|
||
|
|
</Dialog.Body>
|
||
|
|
|
||
|
|
<Dialog.Footer>
|
||
|
|
<Button variant="outline" onClick={() => onOpenChange({ open: false })}>
|
||
|
|
Close
|
||
|
|
</Button>
|
||
|
|
</Dialog.Footer>
|
||
|
|
<Dialog.CloseTrigger />
|
||
|
|
</Dialog.Content>
|
||
|
|
</Dialog.Positioner>
|
||
|
|
</Dialog.Root>
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
const get_7_day_range_url = () => {
|
||
|
|
const base_url = '/api/v2/comm_coor_ivans'
|
||
|
|
let today = new Date();
|
||
|
|
let sevenDaysAgo = new Date(today);
|
||
|
|
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
|
||
|
|
|
||
|
|
sevenDaysAgo = sevenDaysAgo.toLocaleDateString('en-CA');
|
||
|
|
today = today.toLocaleDateString('en-CA');
|
||
|
|
|
||
|
|
const url_with_dates = base_url + '?start_date=' + sevenDaysAgo + '&end_date=' + today;
|
||
|
|
return url_with_dates;
|
||
|
|
}
|
||
|
|
|
||
|
|
const seven_day_url = get_7_day_range_url();
|
||
|
|
|
||
|
|
const {data: apiData, isLoading, error} = VdapApi(seven_day_url);
|
||
|
|
|
||
|
|
if (isLoading) return (
|
||
|
|
<Flex w="100%" h="100%" bg="gray.800" borderRadius="md" align="center" justify="center">
|
||
|
|
<Spinner size="xl" color="blue.400" thickness="4px"/>
|
||
|
|
</Flex>
|
||
|
|
);
|
||
|
|
|
||
|
|
if (error) return (
|
||
|
|
<Flex w="100%" h="100%" bg="gray.800" borderRadius="md" align="center" justify="center" p={4}>
|
||
|
|
<Text color="red.400">{error}</Text>
|
||
|
|
</Flex>
|
||
|
|
);
|
||
|
|
|
||
|
|
if (apiData.length === 0) return (
|
||
|
|
<Flex height="100%" width="100%" align="center" justify="center" bg="gray.800" borderRadius="md">
|
||
|
|
<Text color="gray.400">No flight level data available.</Text>
|
||
|
|
</Flex>
|
||
|
|
);
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Flex w="100%" h="100%" direction="column" bg="gray.800" borderRadius="md" align="center" justify="center" p={4}>
|
||
|
|
<Flex direction="row" gap={4}>
|
||
|
|
<Text color="gray.400">Volcano</Text>
|
||
|
|
<Text color="gray.400">Report Number</Text>
|
||
|
|
<Text color="gray.400">Report Send Time</Text>
|
||
|
|
<Text color="gray.400">Preparer</Text>
|
||
|
|
<Text color="gray.400">Summary</Text>
|
||
|
|
<Text color="gray.400">Attachments</Text>
|
||
|
|
</Flex>
|
||
|
|
{apiData.map((item, index) => {
|
||
|
|
const context_str = item.volcano_name + " " + "•" + " " + item.send_time;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Flex direction="row" key={index} gap={4}>
|
||
|
|
<Text color="gray.400">{item.volcano_name}</Text>
|
||
|
|
<Text color="gray.400">{item.report_num}</Text>
|
||
|
|
<Text color="gray.400">{item.send_time}</Text>
|
||
|
|
<Text color="gray.400">{item.preparer}</Text>
|
||
|
|
<Button onClick={() => setIsSummaryOpen(true)} color="gray.400">View</Button>
|
||
|
|
<SummaryDialog
|
||
|
|
open={isSummaryOpen}
|
||
|
|
onOpenChange={(e) => setIsSummaryOpen(e.open)}
|
||
|
|
item={item}
|
||
|
|
/>
|
||
|
|
{item.files.map((item, index) => {
|
||
|
|
const $file_name = item.name;
|
||
|
|
const $url = item.url;
|
||
|
|
const $type = item.type;
|
||
|
|
|
||
|
|
if ($type === "pdf") return (
|
||
|
|
<>
|
||
|
|
<Button onClick={() => setIsFileOpen(true)}>{$type}</Button>
|
||
|
|
<FileDialog
|
||
|
|
open={isFileOpen}
|
||
|
|
onOpenChange={(e) => setIsFileOpen(e.open)}
|
||
|
|
item={item}
|
||
|
|
context={context_str}
|
||
|
|
/>
|
||
|
|
</>
|
||
|
|
)
|
||
|
|
})}
|
||
|
|
</Flex>
|
||
|
|
)
|
||
|
|
})}
|
||
|
|
<Flex>
|
||
|
|
</Flex>
|
||
|
|
</Flex>
|
||
|
|
);
|
||
|
|
}
|