Skip to content

Commit

Permalink
feat: Added auditing site
Browse files Browse the repository at this point in the history
  • Loading branch information
Dexagod committed Apr 29, 2024
1 parent 83137ce commit 2dfe9ce
Show file tree
Hide file tree
Showing 14 changed files with 699 additions and 0 deletions.
29 changes: 29 additions & 0 deletions demo/sites/auditingsite/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@solidlab/uma-demo-auditing",
"version": "0.1.0",
"private": true,
"dependencies": {
"@comunica/query-sparql": "^2.6.9",
"@inrupt/solid-client-authn-browser": "^1.14.0",
"@mui/material": "^5.15.15",
"n3": "^1.17.3",
"uuid": "^9.0.1"
},
"scripts": {
"dev": "yarn run -T react-scripts start",
"start": "yarn run -T serve -s build -l 5003",
"build": "yarn run -T react-scripts build"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
11 changes: 11 additions & 0 deletions demo/sites/auditingsite/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Auditing Interface</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Binary file added demo/sites/auditingsite/public/store.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 85 additions & 0 deletions demo/sites/auditingsite/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
.App {
text-align: center;
height: 100vh;
background-color: rgb(235, 235, 235);
}

.App-logo {
height: 40vmin;
pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}

.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}

.App-link {
color: #61dafb;
}

@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

.selected {
background-color: lightblue !important;
}

.grid-container {
height: 70vh;
}

#retrievals-listing {
}

.retrieval-resource-card {
padding: 5px;
margin: 5px;
width: 100%;
word-wrap: break-word;
height: 5em;
text-align: left;
}

#audit-page {
height: 70vh;
}

.text-display {
margin: 2em;
overflow-y: scroll;
text-align: left;
white-space: pre-wrap;
height: 80%;
/* todo: fix height problem here other way. */
}

#contents {
}

.left-border {
border-left: 1px solid black;
}

#store-page {
background-color: #f6f6f6;
padding: 2em;
}
13 changes: 13 additions & 0 deletions demo/sites/auditingsite/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

import './App.css';

import ClippedDrawer from "./components/Drawer";

export default function App() {

return (
<div className="App">
<ClippedDrawer />
</div>
)
}
14 changes: 14 additions & 0 deletions demo/sites/auditingsite/src/components/AuditEntryPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { AuditEntry } from "../util/Types";

export default function AuditEntryPage({entry}: {entry: AuditEntry}) {
return (
<div id="audit-page">
<h2>{entry.resourceId}</h2>
<div className="text-display">
<p>
{JSON.stringify(entry.contract, null, 2)}
</p>
</div>
</div>
)
}
87 changes: 87 additions & 0 deletions demo/sites/auditingsite/src/components/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { useState, useEffect } from 'react';
import Box from '@mui/material/Box';
import Drawer from '@mui/material/Drawer';
import AppBar from '@mui/material/AppBar';
import CssBaseline from '@mui/material/CssBaseline';
import Toolbar from '@mui/material/Toolbar';
import List from '@mui/material/List';
import Typography from '@mui/material/Typography';
import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import StorePage from './StorePage';
import { Divider } from '@mui/material';

const drawerWidth = 250;

// Map stores on their audits
export interface StoreInfo {
name: string,
site: string,
audit: string,
logo: string,
}

const stores: StoreInfo[] = [{
name: "De Buurtwinkel",
site: "http://localhost:5002/",
audit: "http://localhost:5123/audit",
logo: "store.jpg"
}]

export default function ClippedDrawer() {

const [selected, setSelected] = useState<StoreInfo | undefined>(undefined)

return (
<Box sx={{ display: 'flex' }}>
<CssBaseline />
<AppBar position="fixed" sx={{ zIndex: (theme) => theme.zIndex.drawer + 1 }}>
<Toolbar>
<Typography variant="h6" noWrap component="div">
Auto Auditing Platform
</Typography>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
sx={{
width: drawerWidth,
flexShrink: 0,
[`& .MuiDrawer-paper`]: { width: drawerWidth, boxSizing: 'border-box' },
}}
>
<Toolbar />
<Box sx={{ overflow: 'auto' }}>
<List>

<ListItem key='registered' disablePadding>
<ListItemButton>
<ListItemText primary="Registered Stores" />
</ListItemButton>
</ListItem>
<Divider />
{stores.map((store, index) => (
<ListItem key={store.name} onClick={() => setSelected(store)} disablePadding
className={selected && selected?.name === store.name ? "selected" : ""} >
<ListItemButton>
<ListItemIcon>
<img src={store.logo} style={{width: "2rem", height: "2rem"}} />
</ListItemIcon>
<ListItemText primary={store.name} />
</ListItemButton>
</ListItem>
))}
</List>
</Box>
</Drawer>
<Box id="contents" component="main" sx={{ flexGrow: 1, p: 3 }}>
<Toolbar />
{
selected && <StorePage store={selected} />
}
</Box>
</Box>
);
}
66 changes: 66 additions & 0 deletions demo/sites/auditingsite/src/components/StorePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* eslint-disable max-len */
import React, { useEffect, useState } from "react";
import { StoreInfo } from "./Drawer";
import { Card, Grid, Typography } from "@mui/material";
import { AuditEntry } from "../util/Types";
import AuditEntryPage from "./AuditEntryPage";


export default function StorePage({ store }: { store: StoreInfo }) {

const [auditEntries, setAuditEntries] = useState<AuditEntry[]>([])
const [selectedEntry, setSelectedEntry] = useState<AuditEntry | undefined>(undefined)

useEffect(() => {
async function fetchAuditEntries() {
const res = await fetch(store.audit)
const parsedEntries = await res.json() as any;
return parsedEntries.map((e: any) => {
e.timestamp = new Date(e.timestamp)
return e
})
}
fetchAuditEntries().then(entries => setAuditEntries(entries)) //todo: uncomment

}, [])

return(
<div id="store-page">
<h1><a href={store.site}>{store.name}</a></h1>
<div className="flex-row">
{/* Data Retrievals */}
<Grid container className="grid-container">
<Grid item xs={4}>
<div id="retrievals-listing">
<Grid container>
{auditEntries.map(entry =>
<Card key={entry.token} className={`retrieval-resource-card ${
// todo: better equals check?
selectedEntry === entry ? "selected" : ""
}`} onClick={() => { setSelectedEntry(entry) }}>
<Typography variant="h6">
{entry.resourceId}
</Typography>
<Typography variant="subtitle1">
{entry.timestamp.toISOString()}
</Typography>
</Card>
)}
</Grid>
</div>
</Grid>
<Grid item xs={8} className="left-border">
{
selectedEntry
? <AuditEntryPage entry={selectedEntry} />
: <div />
}
</Grid>

</Grid>
</div>
</div>
)


}
Loading

0 comments on commit 2dfe9ce

Please sign in to comment.