diff --git a/backend/src/index.ts b/backend/src/index.ts
index 5206dc4e..f4e584f6 100644
--- a/backend/src/index.ts
+++ b/backend/src/index.ts
@@ -3,7 +3,10 @@ import cors from 'cors';
import dotenv from 'dotenv';
import uploadRoutes from './routes/upload';
import allLogs from './routes/getAllLogs';
+import getStats from './routes/getStats';
+import logtypeStatus from './routes/logTypeStatus';
import connectToDatabase from './db/connect';
+import severityInfo from './routes/severityInfo';
dotenv.config();
@@ -24,6 +27,9 @@ app.get('/', (req: Request, res: Response): void => {
app.use('/api', uploadRoutes);
app.use('/api', allLogs);
+app.use('/api', getStats)
+app.use('/api', logtypeStatus)
+app.use('/api', severityInfo)
app.listen(PORT, (): void => {
console.log(`Server is running on http://localhost:${PORT}`);
diff --git a/backend/src/routes/getStats.ts b/backend/src/routes/getStats.ts
new file mode 100644
index 00000000..9084ff80
--- /dev/null
+++ b/backend/src/routes/getStats.ts
@@ -0,0 +1,177 @@
+import express from 'express';
+import { Request, Response } from 'express';
+import { LinuxLogModel } from '../models/LinuxLogModel';
+
+const router = express.Router();
+
+router.get('/stats', async (req: Request, res: Response) => {
+ try {
+ const startDate = new Date();
+ startDate.setDate(startDate.getDate() - 90); // 90 days ago
+
+ const totalLogsAgg = await LinuxLogModel.aggregate([
+ {
+ $match: { timestamp: { $gte: startDate } }
+ },
+ {
+ $group: {
+ _id: {
+ year: { $year: '$timestamp' },
+ month: { $month: '$timestamp' },
+ day: { $dayOfMonth: '$timestamp' },
+ },
+ count: { $sum: 1 },
+ }
+ },
+ {
+ $sort: {
+ "_id.year": 1,
+ "_id.month": 1,
+ "_id.day": 1,
+ }
+ }
+ ]);
+
+ const errorLogsAgg = await LinuxLogModel.aggregate([
+ {
+ $match: {
+ timestamp: { $gte: startDate },
+ severity: { $in: ['ERROR'] }
+ },
+ },
+ {
+ $group: {
+ _id: {
+ year: { $year: '$timestamp' },
+ month: { $month: '$timestamp' },
+ day: { $dayOfMonth: '$timestamp' },
+ },
+ count: { $sum: 1 },
+ }
+ },
+ {
+ $sort: {
+ "_id.year": 1,
+ "_id.month": 1,
+ "_id.day": 1,
+ }
+ }
+ ]);
+
+ const warningLogsAgg = await LinuxLogModel.aggregate([
+ {
+ $match: {
+ timestamp: { $gte: startDate },
+ severity: { $in: ['WARNING'] } // Adjust this based on your severity levels
+ },
+ },
+ {
+ $group: {
+ _id: {
+ year: { $year: '$timestamp' },
+ month: { $month: '$timestamp' },
+ day: { $dayOfMonth: '$timestamp' },
+ },
+ count: { $sum: 1 },
+ }
+ },
+ {
+ $sort: {
+ "_id.year": 1,
+ "_id.month": 1,
+ "_id.day": 1,
+ }
+ }
+ ]);
+
+
+ // Format Helper to build a 90 days array
+ const totalLogsData = buildDailyArray(totalLogsAgg, startDate);
+ const errorLogsData = buildDailyArray(errorLogsAgg, startDate);
+ const warningLogsData = buildDailyArray(warningLogsAgg, startDate);
+
+ // sum up total logs
+ const totalLogsSum = totalLogsData.reduce((acc, count) => acc + count, 0);
+ const errorLogsSum = errorLogsData.reduce((acc, count) => acc + count, 0);
+ const warningLogsSum = warningLogsData.reduce((acc, count) => acc + count, 0);
+
+ //compute tends
+ const totalLogsTend = computeTrend(totalLogsData);
+ const errorLogsTend = computeTrend(errorLogsData);
+ const warningLogsTend = computeTrend(warningLogsData);
+
+
+
+ res.json([
+ {
+ title: "Total Logs",
+ value: totalLogsSum, // e.g. "14k" or a number
+ interval: "Last 90 days",
+ trend: totalLogsTend, // "up", "down", or "neutral"
+ data: totalLogsData, // [0, 3, 5, 2, ...] for 180 days
+ },
+ {
+ title: "Error Count",
+ value: errorLogsSum,
+ interval: "Last 90 days",
+ trend: errorLogsTend,
+ data: errorLogsData,
+ },
+ {
+ title: "Warning Count",
+ value: warningLogsSum,
+ interval: "Last 90 days",
+ trend: warningLogsTend,
+ data: warningLogsData,
+ },
+ ])
+
+
+
+ } catch (error) {
+ console.error(error);
+ res.status(500).json({ error: "Something went wrong." });
+ }
+});
+
+function buildDailyArray(
+ aggResults: { _id: { year: number; month: number; day: number }; count: number }[],
+ startDate: Date
+): number[] {
+ const daysCount = 90;
+ const dailyArray = new Array(daysCount).fill(0);
+
+ for (const doc of aggResults) {
+ const { year, month, day } = doc._id;
+ const thisDate = new Date(year, month - 1, day); // month is 0-indexed
+ const index = Math.floor((thisDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
+
+ if (index >= 0 && index < daysCount) {
+ dailyArray[index] = doc.count;
+ }
+ }
+
+ return dailyArray;
+}
+
+
+function computeTrend(data: number[]) {
+ if (data.length < 2) return "neutral";
+
+ const recentValue = data[data.length - 1];
+ const previousValue = data[data.length - 2];
+
+ if (recentValue > previousValue) {
+ return "up";
+ } else if (recentValue < previousValue) {
+ return "down";
+ } else {
+ return "neutral";
+ }
+}
+
+
+export default router;
+
+
+
diff --git a/backend/src/routes/logTypeStatus.ts b/backend/src/routes/logTypeStatus.ts
new file mode 100644
index 00000000..0531b5ca
--- /dev/null
+++ b/backend/src/routes/logTypeStatus.ts
@@ -0,0 +1,37 @@
+import express from 'express';
+import { Request, Response } from 'express';
+import { LinuxLogModel } from '../models/LinuxLogModel';
+
+const router = express.Router();
+
+router.get('/logtypeStatus', async (req: Request, res: Response) => {
+ try {
+ const syslogCount = await LinuxLogModel.countDocuments({ logType: 'SYSLOG' });
+ const windowlogCount = await LinuxLogModel.countDocuments({ logType: 'WINDOWLOG' });
+ const authlogCount = await LinuxLogModel.countDocuments({ logType: 'AUTH' });
+ const kernelCount = await LinuxLogModel.countDocuments({ logType: 'KERNEL' });
+ const unknownCount = await LinuxLogModel.countDocuments({ logType: { $regex: 'UNKNOWN' } });
+
+ const data = [
+ { label: "SYSLOG", value: syslogCount },
+ { label: "WINDOWLOG", value: windowlogCount },
+ { label: "AUTHLOG", value: authlogCount },
+ { label: "KERNEL", value: kernelCount },
+ { label: "UNKNOWN", value: unknownCount },
+ ];
+
+ res.json(data);
+
+
+ } catch (error) {
+ console.error(error);
+ res.status(500).json({ error: "Something went wrong." });
+ }
+});
+
+
+
+export default router;
+
+
+
diff --git a/backend/src/routes/severityInfo.ts b/backend/src/routes/severityInfo.ts
new file mode 100644
index 00000000..bd65113a
--- /dev/null
+++ b/backend/src/routes/severityInfo.ts
@@ -0,0 +1,74 @@
+// total no of each severity "INFO" | "WARNING" | "ERROR" | "CRITICAL" and from last 7 months count for each severity in following format const [logData, setLogData] = React.useState({
+// info: [0, 0, 0, 0, 0, 0, 0],
+// warning: [0, 0, 0, 0, 0, 0, 0],
+// error: [0, 0, 0, 0, 0, 0, 0],
+// critical: [0, 0, 0, 0, 0, 0, 0],
+// });
+
+import express from 'express';
+import { Request, Response } from 'express';
+import { LinuxLogModel } from '../models/LinuxLogModel';
+
+const router = express.Router();
+
+router.get('/severityInfo', async (req: Request, res: Response) => {
+ try {
+
+ const info = [0, 0, 0, 0, 0, 0, 0];
+ const warning = [0, 0, 0, 0, 0, 0, 0];
+ const error = [0, 0, 0, 0, 0, 0, 0];
+ const critical = [0, 0, 0, 0, 0, 0, 0];
+
+ // Get monthly data for the last 7 months
+ for (let i = 0; i < 7; i++) {
+ const monthStart = new Date();
+ monthStart.setMonth(monthStart.getMonth() - i);
+ monthStart.setDate(1);
+ monthStart.setHours(0, 0, 0, 0);
+
+ const monthEnd = new Date(monthStart);
+ monthEnd.setMonth(monthStart.getMonth() + 1);
+ monthEnd.setDate(0);
+ monthEnd.setHours(23, 59, 59, 999);
+
+ info[6 - i] = await LinuxLogModel.countDocuments({
+ severity: 'INFO',
+ timestamp: { $gte: monthStart, $lte: monthEnd }
+ });
+
+ warning[6 - i] = await LinuxLogModel.countDocuments({
+ severity: 'WARNING',
+ timestamp: { $gte: monthStart, $lte: monthEnd }
+ });
+
+ error[6 - i] = await LinuxLogModel.countDocuments({
+ severity: 'ERROR',
+ timestamp: { $gte: monthStart, $lte: monthEnd }
+ });
+
+ critical[6 - i] = await LinuxLogModel.countDocuments({
+ severity: 'CRITICAL',
+ timestamp: { $gte: monthStart, $lte: monthEnd }
+ });
+ }
+
+ // Prepare response with total counts and monthly data
+ res.json({
+ info,
+ warning,
+ error,
+ critical,
+ });
+
+ } catch (error) {
+ console.error(error);
+ res.status(500).json({ error: "Something went wrong." });
+ }
+});
+
+
+
+export default router;
+
+
+
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 3da335e0..f8040678 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -26,7 +26,6 @@
"@react-spring/web": "^9.7.5",
"d3": "^7.9.0",
"dayjs": "^1.11.13",
- "leaflet": "^1.9.4",
"lucide-react": "^0.485.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
@@ -4198,7 +4197,8 @@
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==",
- "license": "BSD-2-Clause"
+ "license": "BSD-2-Clause",
+ "peer": true
},
"node_modules/levn": {
"version": "0.4.1",
diff --git a/frontend/package.json b/frontend/package.json
index 9982b006..063dd9ed 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -28,7 +28,6 @@
"@react-spring/web": "^9.7.5",
"d3": "^7.9.0",
"dayjs": "^1.11.13",
- "leaflet": "^1.9.4",
"lucide-react": "^0.485.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
diff --git a/frontend/src/components/Chat.jsx b/frontend/src/components/Chat.jsx
index e3b43164..7fa4058e 100644
--- a/frontend/src/components/Chat.jsx
+++ b/frontend/src/components/Chat.jsx
@@ -1,17 +1,96 @@
-import { Stack } from "@mui/material";
+import {
+ Box,
+ IconButton,
+ Paper,
+ Stack,
+ TextField,
+ Typography,
+} from "@mui/material";
+import SendIcon from "@mui/icons-material/Send";
+import { useEffect, useRef, useState } from "react";
export default function Chat() {
+ const [messages, setMessages] = useState([
+ { id: 1, text: "Hello, how can I help you?", sender: "bot" },
+ { id: 2, text: "I need help analyzing my logs", sender: "user" },
+ ]);
+ const [newMessage, setNewMessage] = useState("");
+ const messagesEndRef = useRef(null);
+
+ const handleSend = () => {
+ if (newMessage.trim()) {
+ setMessages([
+ ...messages,
+ { id: messages.length + 1, text: newMessage, sender: "user" },
+ ]);
+ setNewMessage("");
+ }
+ };
+
+ useEffect(() => {
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
+ }, [messages]);
+
return (
- Chat
+
+ {messages.map((message) => (
+
+
+ {message.text}
+
+
+ ))}
+
+
+
+
+ setNewMessage(e.target.value)}
+ onKeyDown={(e) => e.key === "Enter" && handleSend()}
+ />
+
+
+
+
);
}
diff --git a/frontend/src/components/HighlightedCard.jsx b/frontend/src/components/HighlightedCard.jsx
index 940b5fd2..7b655cf8 100644
--- a/frontend/src/components/HighlightedCard.jsx
+++ b/frontend/src/components/HighlightedCard.jsx
@@ -7,10 +7,13 @@ import ChevronRightRoundedIcon from "@mui/icons-material/ChevronRightRounded";
import InsightsRoundedIcon from "@mui/icons-material/InsightsRounded";
import useMediaQuery from "@mui/material/useMediaQuery";
import { useTheme } from "@mui/material/styles";
+import { useRecoilState } from "recoil";
+import { activeViewState } from "../utils/state";
export default function HighlightedCard() {
const theme = useTheme();
const isSmallScreen = useMediaQuery(theme.breakpoints.down("sm"));
+ const [_, setActiveViewState] = useRecoilState(activeViewState);
return (
@@ -33,6 +36,9 @@ export default function HighlightedCard() {
color="primary"
endIcon={}
fullWidth={isSmallScreen}
+ onClick={() => {
+ setActiveViewState("chat");
+ }}
>
Get insights
diff --git a/frontend/src/components/LogAnalyzedBarGraph.jsx b/frontend/src/components/LogAnalyzedBarGraph.jsx
new file mode 100644
index 00000000..03c81158
--- /dev/null
+++ b/frontend/src/components/LogAnalyzedBarGraph.jsx
@@ -0,0 +1,164 @@
+import * as React from "react";
+import Card from "@mui/material/Card";
+import CardContent from "@mui/material/CardContent";
+import Chip from "@mui/material/Chip";
+import Typography from "@mui/material/Typography";
+import Stack from "@mui/material/Stack";
+import { BarChart } from "@mui/x-charts/BarChart";
+import { useTheme } from "@mui/material/styles";
+import severityInfo from "../utils/api/severityInfo";
+
+export default function LogAnalyzedBarChart() {
+ const theme = useTheme();
+ const colorPalette = [
+ (theme.vars || theme).palette.info.main, // INFO
+ (theme.vars || theme).palette.warning.main, // WARNING
+ (theme.vars || theme).palette.error.main, // ERROR
+ (theme.vars || theme).palette.error.dark, // CRITICAL
+ ];
+
+ const [logData, setLogData] = React.useState({
+ info: [0, 0, 0, 0, 0, 0, 0],
+ warning: [0, 0, 0, 0, 0, 0, 0],
+ error: [0, 0, 0, 0, 0, 0, 0],
+ critical: [0, 0, 0, 0, 0, 0, 0],
+ });
+ const [totalLogs, setTotalLogs] = React.useState(0);
+ const [percentageChange, setPercentageChange] = React.useState(0);
+ const [months, setMonths] = React.useState([]);
+
+ React.useEffect(() => {
+ // Get last 7 months
+ const getLastSevenMonths = () => {
+ const monthNames = [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+ ];
+ const result = [];
+ const currentDate = new Date();
+ const currentMonth = currentDate.getMonth();
+
+ for (let i = 6; i >= 0; i--) {
+ const monthIndex = (currentMonth - i + 12) % 12;
+ result.push(monthNames[monthIndex]);
+ }
+
+ return result;
+ };
+
+ setMonths(getLastSevenMonths());
+
+ // Fetch log data from backend
+ const fetchLogData = async () => {
+ try {
+ const response = await severityInfo();
+ setLogData(response);
+
+ const total = Object.values(response)
+ .flat()
+ .reduce((sum, val) => sum + val, 0);
+ setTotalLogs(total);
+
+ if (response.percentageChange !== undefined) {
+ setPercentageChange(response.percentageChange);
+ }
+ } catch (error) {
+ console.error("Error fetching log data:", error);
+ }
+ };
+
+ fetchLogData();
+ }, []);
+
+ // Format number with K suffix if >= 1000
+ const formatNumber = (num) => {
+ return num >= 1000 ? `${(num / 1000).toFixed(1)}K` : num.toString();
+ };
+
+ return (
+
+
+
+ Analyzed Logs
+
+
+
+
+ {formatNumber(totalLogs)}
+
+
+
+
+ Logs analyzed in the last 30 days
+
+
+
+
+
+ );
+}
diff --git a/frontend/src/components/LogTypeStatus.jsx b/frontend/src/components/LogTypeStatus.jsx
index 264fc532..4d049d2e 100644
--- a/frontend/src/components/LogTypeStatus.jsx
+++ b/frontend/src/components/LogTypeStatus.jsx
@@ -15,47 +15,15 @@ import System from "@mui/icons-material/Computer";
import Window from "@mui/icons-material/Window";
import Kernel from "@mui/icons-material/Memory";
import Auth from "@mui/icons-material/LockOpen";
+import logtypeStatus from "../utils/api/logtypeStatus";
-const data = [
- { label: "SYSLOG", value: 50000 },
- { label: "WINDOWLOG", value: 35000 },
- { label: "AUTHLOG", value: 10000 },
- { label: "KERNEL", value: 10000 },
- { label: "UNKNOWN", value: 5000 },
-];
-
-const countries = [
- {
- name: "SYSLOG",
- value: 50,
- flag: ,
- color: "hsl(220, 25%, 65%)",
- },
- {
- name: "WINDOWLOG",
- value: 35,
- flag: ,
- color: "hsl(220, 25%, 45%)",
- },
- {
- name: "AUTHLOG",
- value: 10,
- flag: ,
- color: "hsl(220, 25%, 30%)",
- },
- {
- name: "KERNEL",
- value: 10,
- flag: ,
- color: "hsl(220, 25%, 30%)",
- },
- {
- name: "UNKNOWN",
- value: 5,
- flag: ,
- color: "hsl(220, 25%, 20%)",
- },
-];
+// const data = [
+// { label: "SYSLOG", value: 50000 },
+// { label: "WINDOWLOG", value: 35000 },
+// { label: "AUTHLOG", value: 10000 },
+// { label: "KERNEL", value: 10000 },
+// { label: "UNKNOWN", value: 5000 },
+// ];
const StyledText = styled("text", {
shouldForwardProp: (prop) => prop !== "variant",
@@ -120,6 +88,54 @@ const colors = [
];
export default function LogTypeStatus() {
+ const [data, setData] = React.useState([]);
+ const [totalCount, setTotalCount] = React.useState("0");
+ const [loading, setLoading] = React.useState(true);
+
+ React.useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const response = await logtypeStatus();
+ setData(response);
+
+ //convert to string with the K notation
+ const total = response.reduce((acc, item) => acc + item.value, 0);
+ const totalString =
+ total >= 1000 ? `${(total / 1000).toFixed(1)}K` : total.toString();
+ setTotalCount(totalString);
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ } finally {
+ setLoading(false);
+ }
+ };
+ fetchData();
+ }, []);
+ const total = data.reduce((acc, item) => acc + item.value, 0);
+
+ const iconMap = {
+ SYSLOG: { flag: , color: "hsl(220, 25%, 65%)" },
+ WINDOWLOG: { flag: , color: "hsl(220, 25%, 45%)" },
+ AUTHLOG: { flag: , color: "hsl(220, 25%, 30%)" },
+ KERNEL: { flag: , color: "hsl(220, 25%, 30%)" },
+ UNKNOWN: { flag: , color: "hsl(220, 25%, 20%)" },
+ };
+
+ const logData = data.map((item) => {
+ const percentage = total > 0 ? Math.round((item.value / total) * 100) : 0;
+ const defaultIcon = { flag: , color: "hsl(220, 25%, 20%)" };
+ const { flag, color } = iconMap[item.label] || defaultIcon;
+
+ return {
+ name: item.label,
+ value: percentage,
+ flag,
+ color,
+ rawValue: item.value,
+ };
+ });
+
+ if (loading) return Loading...
;
return (
-
+
- {countries.map((country, index) => (
+ {logData.map((country, index) => (
{
+ const fetchData = async () => {
+ try {
+ const response = await fetchStats();
+ setData(response);
+ } catch (error) {
+ console.error("Error fetching data:", error);
+ } finally {
+ setLoading(false);
+ }
+ };
+ fetchData();
+ }, []);
+ if (loading) return Loading...
;
return (
{/* cards */}
@@ -68,16 +52,17 @@ export default function MainGrid() {
-
+
-
+ {/* // TODO: add line Graph to show the trend of the logs over time */}
+ {/*
-
+ */}
);
}
diff --git a/frontend/src/components/PageViewsBarChart.jsx b/frontend/src/components/PageViewsBarChart.jsx
deleted file mode 100644
index b3457522..00000000
--- a/frontend/src/components/PageViewsBarChart.jsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import * as React from "react";
-import Card from "@mui/material/Card";
-import CardContent from "@mui/material/CardContent";
-import Chip from "@mui/material/Chip";
-import Typography from "@mui/material/Typography";
-import Stack from "@mui/material/Stack";
-import { BarChart } from "@mui/x-charts/BarChart";
-import { useTheme } from "@mui/material/styles";
-
-export default function PageViewsBarChart() {
- const theme = useTheme();
- const colorPalette = [
- (theme.vars || theme).palette.primary.dark,
- (theme.vars || theme).palette.primary.main,
- (theme.vars || theme).palette.primary.light,
- ];
- return (
-
-
-
- Analyzed Logs
-
-
-
-
- 12K
-
-
-
-
- Logs analyzed in the last 30 days
-
-
-
-
-
- );
-}
diff --git a/frontend/src/components/StatCard.jsx b/frontend/src/components/StatCard.jsx
index ab804e5e..9f672013 100644
--- a/frontend/src/components/StatCard.jsx
+++ b/frontend/src/components/StatCard.jsx
@@ -9,18 +9,23 @@ import Typography from "@mui/material/Typography";
import { SparkLineChart } from "@mui/x-charts/SparkLineChart";
import { areaElementClasses } from "@mui/x-charts/LineChart";
-function getDaysInMonth(month, year) {
- const date = new Date(year, month, 0);
- const monthName = date.toLocaleDateString("en-US", {
- month: "short",
- });
- const daysInMonth = date.getDate();
+function getDaysInMonth() {
+ // Create an array of 90 days from today
const days = [];
- let i = 1;
- while (days.length < daysInMonth) {
- days.push(`${monthName} ${i}`);
- i += 1;
+ const startDate = new Date();
+
+ for (let i = 0; i < 90; i++) {
+ const currentDate = new Date(startDate);
+ currentDate.setDate(startDate.getDate() + i);
+
+ const monthName = currentDate.toLocaleDateString("en-US", {
+ month: "short",
+ });
+ const dayOfMonth = currentDate.getDate();
+
+ days.push(`${monthName} ${dayOfMonth}`);
}
+
return days;
}
@@ -37,8 +42,7 @@ function AreaGradient({ color, id }) {
export default function StatCard({ title, value, interval, trend, data }) {
const theme = useTheme();
- const daysInWeek = getDaysInMonth(4, 2024);
-
+ const daysInWeek = getDaysInMonth();
const trendColors = {
up:
theme.palette.mode === "light"
diff --git a/frontend/src/utils/api/fetchStats.js b/frontend/src/utils/api/fetchStats.js
new file mode 100644
index 00000000..92b46b73
--- /dev/null
+++ b/frontend/src/utils/api/fetchStats.js
@@ -0,0 +1,13 @@
+export default async function fetchStats() {
+ const data = await fetch(`${import.meta.env.VITE_BACKEND_URL}/api/stats`)
+
+ if(!data.ok) {
+ throw new Error("Network response was not ok" + data.statusText);
+ }
+
+ const dataJson = await data.json();
+ if (!dataJson) {
+ throw new Error("No data found");
+ }
+ return dataJson;
+}
diff --git a/frontend/src/utils/api/logtypeStatus.js b/frontend/src/utils/api/logtypeStatus.js
new file mode 100644
index 00000000..b3bca350
--- /dev/null
+++ b/frontend/src/utils/api/logtypeStatus.js
@@ -0,0 +1,13 @@
+export default async function logtypeStatus() {
+ const data = await fetch(`${import.meta.env.VITE_BACKEND_URL}/api/logtypeStatus`);
+
+ if(!data.ok) {
+ throw new Error("Network response was not ok" + data.statusText);
+ }
+
+ const dataJson = await data.json();
+ if (!dataJson) {
+ throw new Error("No data found");
+ }
+ return dataJson;
+}
diff --git a/frontend/src/utils/api/severityInfo.js b/frontend/src/utils/api/severityInfo.js
new file mode 100644
index 00000000..6c7e8350
--- /dev/null
+++ b/frontend/src/utils/api/severityInfo.js
@@ -0,0 +1,14 @@
+
+export default async function severityInfo() {
+ const data = await fetch(`${import.meta.env.VITE_BACKEND_URL}/api/severityInfo`)
+
+ if(!data.ok) {
+ throw new Error("Network response was not ok" + data.statusText);
+ }
+
+ const dataJson = await data.json();
+ if (!dataJson) {
+ throw new Error("No data found");
+ }
+ return dataJson;
+}