From 193a11989ddfdd3eca370ed966edf4aa807c1164 Mon Sep 17 00:00:00 2001 From: JonathanVarild Date: Sun, 22 Dec 2024 04:20:34 +0100 Subject: [PATCH] Added data to data report view --- src/presenters/DataReportPresenter.jsx | 13 +++++- src/store/interface/dataReport.js | 57 ++++++++++++++++++++++ src/store/interface/index.js | 8 ++-- src/views/DataReportView.jsx | 65 +++++++++++--------------- 4 files changed, 101 insertions(+), 42 deletions(-) create mode 100644 src/store/interface/dataReport.js diff --git a/src/presenters/DataReportPresenter.jsx b/src/presenters/DataReportPresenter.jsx index 27b6fd3..485b67f 100644 --- a/src/presenters/DataReportPresenter.jsx +++ b/src/presenters/DataReportPresenter.jsx @@ -1,7 +1,18 @@ +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; import DataReportView from "../views/DataReportView"; +import { fetchDataReport } from "../store/interface/dataReport"; function DataReport(props) { - return ; + const dataReport = useSelector((state) => state.interface.dataReport); + const userInfo = useSelector((state) => state.interface.authenticate.userInfo); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(fetchDataReport()); + }, [dispatch]); + + return ; } export default DataReport; diff --git a/src/store/interface/dataReport.js b/src/store/interface/dataReport.js new file mode 100644 index 0000000..1de8e70 --- /dev/null +++ b/src/store/interface/dataReport.js @@ -0,0 +1,57 @@ +import { createAsyncThunk } from "@reduxjs/toolkit"; +import { fetchResolvedCB } from "./utilities"; + +const apiUrl = import.meta.env.VITE_API_URL; + +export const dataReportInitalState = { + dataReport: { + status: "idle", + requestId: null, + error: null, + data: null, + }, +}; + +export const fetchDataReport = createAsyncThunk("interface/fetchDataReport", async (_, { getState, abort, requestId }) => { + const state = getState().interface; + + if (state.dataReport.requestId !== requestId) return abort("Request already in progress."); + + return await fetch(apiUrl + "/api/data_report", { + method: "POST", + headers: { + "Content-type": "application/json; charset=UTF-8", + }, + credentials: "include", + }).then(fetchResolvedCB); +}); + +export function dataReportBuilder(builder) { + builder + .addCase(fetchDataReport.pending, (state, action) => { + if (state.dataReport.requestId === null) { + state.dataReport.status = "loading"; + state.dataReport.requestId = action.meta.requestId; + } + }) + .addCase(fetchDataReport.fulfilled, (state, action) => { + if (state.dataReport.requestId === action.meta.requestId) { + state.dataReport.status = "idle"; + state.dataReport.requestId = null; + state.dataReport.data = { + agreements: action.payload.agreements, + loginLogs: action.payload.login_logs, + reportLogs: action.payload.report_logs, + favoriteLines: action.payload.favorite_lines, + userData: action.payload.userData, + }; + } + }) + .addCase(fetchDataReport.rejected, (state, action) => { + if (state.dataReport.requestId === action.meta.requestId) { + state.dataReport.status = "failed"; + state.dataReport.requestId = null; + state.dataReport.error = action.error.message; + } + }); +} diff --git a/src/store/interface/index.js b/src/store/interface/index.js index e83ffee..b5ca531 100644 --- a/src/store/interface/index.js +++ b/src/store/interface/index.js @@ -8,6 +8,7 @@ import { updatePasswordInitialState, updatePasswordBuilder } from "./updatePassw import { searchInitialState, searchBuilder } from "./search"; import { trendingBuilder, trendingInitalState } from "./trending"; import { deleteAccountBuilder, deleteAccountInitialState, getDeleteAccountMiddleware } from "./deleteAccount"; +import { dataReportBuilder, dataReportInitalState } from "./dataReport"; const interfaceSlice = createSlice({ name: "interface", @@ -50,7 +51,8 @@ const interfaceSlice = createSlice({ ...updatePasswordInitialState, ...searchInitialState, ...trendingInitalState, - ...deleteAccountInitialState + ...deleteAccountInitialState, + ...dataReportInitalState, }, reducers: { toggleNavigation: (state) => { @@ -132,7 +134,8 @@ const interfaceSlice = createSlice({ updatePasswordBuilder(builder); searchBuilder(builder); trendingBuilder(builder); - deleteAccountBuilder(builder) + deleteAccountBuilder(builder); + dataReportBuilder(builder); }, }); @@ -157,4 +160,3 @@ export default interfaceSlice.reducer; export const logoutMiddlewareFunction = getLogoutMiddleware(dequeuePopup); export const deleteAccountMiddlewareFunction = getDeleteAccountMiddleware(dequeuePopup); - diff --git a/src/views/DataReportView.jsx b/src/views/DataReportView.jsx index 73ecedb..174ea21 100644 --- a/src/views/DataReportView.jsx +++ b/src/views/DataReportView.jsx @@ -1,10 +1,19 @@ import styles from "../css/DataReport.module.css"; +import LoadingSpinnerView from "../views/LoadingSpinnerView"; function DataReportView(props) { + if (props.status === "failed") { + return
We could not find any data.
; + } + + if (props.data === null) { + return ; + } + return (

User data report

-
A new report will be available for generation in 24 hours. Please save this report if you want to view it again.
+
This report is showing all account information that we store in our database.

User data:

@@ -16,27 +25,23 @@ function DataReportView(props) { - + - + - - - - - + - + - +
user_id{props.data.userData.id}
username{props.data.userData.username}
email
password_hash{props.data.userData.email}
date_of_birth{props.data.userData.date_of_birth}
registration_date{props.data.userData.registration_date}
@@ -48,17 +53,7 @@ function DataReportView(props) { user_id - {[{ lineID: "2123414123132", userID: "3" }].map(renderFavoriteLineCB)} - -

Favorite stations:

- - - - - - - - {[{ stationID: "2123414123132", userID: "3" }].map(renderFavoriteStationCB)} + {props.data.favoriteLines.map(renderFavoriteLineCB)}
station_iduser_id

Login logs:

@@ -68,7 +63,7 @@ function DataReportView(props) { - {[{ time: "YYYY-MM-DD HH:MM:SS", ip: "192.168.1.1" }].map(renderLoginCB)} + {props.data.loginLogs.map(renderLoginCB)}
ip

Report logs:

@@ -78,7 +73,7 @@ function DataReportView(props) { - {[{ time: "YYYY-MM-DD HH:MM:SS", ip: "192.168.1.1" }].map(renderReportCB)} + {props.data.reportLogs.map(renderReportCB)}
ip

Agreement logs:

@@ -89,21 +84,15 @@ function DataReportView(props) { - - {[ - { time: "YYYY-MM-DD HH:MM:SS", type: "terms_of_service", ip: "192.168.1.1" }, - { time: "YYYY-MM-DD HH:MM:SS", type: "data_policy", ip: "192.168.1.1" }, - ].map(renderAgreementCB)} - + {props.data.agreements.map(renderAgreementCB)}
ip
-
); function renderLoginCB(login) { return ( - - {login.time} + + {login.timestamp} (UTC +0) {login.ip} ); @@ -111,8 +100,8 @@ function DataReportView(props) { function renderReportCB(report) { return ( - - {report.time} + + {report.timestamp} (UTC +0) {report.ip} ); @@ -120,8 +109,8 @@ function DataReportView(props) { function renderAgreementCB(agreement) { return ( - - {agreement.time} + + {agreement.timestamp} (UTC +0) {agreement.type} {agreement.ip} @@ -130,8 +119,8 @@ function DataReportView(props) { function renderFavoriteLineCB(favoriteLine) { return ( - - {favoriteLine.lineID} + + {favoriteLine.line_id} {favoriteLine.userID} );