Skip to content

Commit

Permalink
feat: display dashboard (#234)
Browse files Browse the repository at this point in the history
Refs: closes #191

## Summary

Display dashboard.
  • Loading branch information
joaotomaspinheiro authored Jun 27, 2024
1 parent a8e875d commit 5e08c9c
Show file tree
Hide file tree
Showing 23 changed files with 818 additions and 30 deletions.
17 changes: 17 additions & 0 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
]
},
"dependencies": {
"chart.js": "^4.4.3",
"ol": "^9.1.0",
"openapi-fetch": "^0.9.5"
},
Expand Down
9 changes: 8 additions & 1 deletion web/src/lib/components/table/Table.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@
*/
export let sortingOrder: SortingDirection | null = null;
/**
* A space-separated list of the classes of the element.
* @default ""
*/
let className: string = "";
export { className as class };
/**
* Map that contains the sorting state for each column.
* @example
Expand Down Expand Up @@ -174,7 +181,7 @@
$: columnsSorting = getColumnsSorting(columns, sortingField, sortingOrder);
</script>
<div class="table-container">
<div class={`table-container ${className}`}>
<table>
<thead>
<tr>
Expand Down
41 changes: 41 additions & 0 deletions web/src/lib/utils/chart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
Chart,
LineElement,
LineController,
LinearScale,
CategoryScale,
PointElement,
Tooltip,
Legend,
DoughnutController,
ArcElement,
BarElement,
BarController,
Filler,
} from "chart.js";
import { getCssVariable } from "./cssVars";

/**
* Set up Chart.js with the required components for the application and a
* custom theme.
*/
export function setupChart() {
Chart.register(
LineElement,
LineController,
LinearScale,
CategoryScale,
PointElement,
Tooltip,
Legend,
DoughnutController,
ArcElement,
BarElement,
BarController,
Filler,
);

Chart.defaults.font.family = "Inter, sans-serif";
Chart.defaults.font.lineHeight = 1.5;
Chart.defaults.color = getCssVariable("--gray-900");
}
9 changes: 9 additions & 0 deletions web/src/lib/utils/color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Retrieves a color with an opacity.
* @param hex Color hexadecimal value.
* @param opacity Value between 0 and 1.
* @returns Hexadecimal color with an opacity.
*/
export function getColorWithOpacity(hex: string, opacity: number) {
return `${hex}${Math.floor(opacity * 255).toString(16)}`;
}
6 changes: 6 additions & 0 deletions web/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@
"signOut.button": "Sign out",
"myInformation": "My information",
"dashboard": "Dashboard",
"dashboard.activeEmployees": "Active employees",
"dashboard.amountOfWarehouses": "Number of warehouses",
"dashboard.amountOfTrucks": "Number of trucks",
"dashboard.containersAdded": "Containers added",
"dashboard.containersByCategory": "Containers by category",
"dashboard.containersByMunicipality": "Containers by municipality",
"map": "Map",
"departure": "Departure",
"arrival": "Arrival",
Expand Down
6 changes: 6 additions & 0 deletions web/src/locales/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@
"signOut.button": "Terminar sessão",
"myInformation": "Minha informação",
"dashboard": "Painel",
"dashboard.activeEmployees": "Colaboradores ativos",
"dashboard.amountOfWarehouses": "Número de armazéns",
"dashboard.amountOfTrucks": "Número de camiões",
"dashboard.containersAdded": "Contentores adicionados",
"dashboard.containersByCategory": "Contentores por categoria",
"dashboard.containersByMunicipality": "Contentores por município",
"map": "Mapa",
"departure": "Partida",
"arrival": "Chegada",
Expand Down
18 changes: 18 additions & 0 deletions web/src/locales/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,24 @@
"dashboard": {
"type": "string"
},
"dashboard.activeEmployees": {
"type": "string"
},
"dashboard.amountOfWarehouses": {
"type": "string"
},
"dashboard.amountOfTrucks": {
"type": "string"
},
"dashboard.containersAdded": {
"type": "string"
},
"dashboard.containersByCategory": {
"type": "string"
},
"dashboard.containersByMunicipality": {
"type": "string"
},
"map": {
"type": "string"
},
Expand Down
3 changes: 3 additions & 0 deletions web/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import "./app.css";
import App from "./App.svelte";
import { setupChart } from "./lib/utils/chart";

setupChart();

const app = new App({
target: document.getElementById("app")!,
Expand Down
28 changes: 8 additions & 20 deletions web/src/routes/backOffice/components/BackOfficeLayout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,23 @@
}
</script>

<div class="main">
<TopBar />
<div class="container">
<SideBar />
<div class="layout">
<slot />
</div>
<TopBar />
<div class="content">
<SideBar />
<div class="layout">
<slot />
</div>
</div>

<style>
.main {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.container {
flex: 1;
.content {
display: flex;
height: calc(100vh - var(--top-bar-height));
}
.layout {
display: flex;
flex: 1;
display: grid;
overflow: auto;
& > * {
flex: 1;
}
}
</style>
12 changes: 9 additions & 3 deletions web/src/routes/backOffice/components/Card.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
*/
let className: string = "";
export { className as class };
/**
* The HTML element that's rendered.
* @default "main"
*/
export let element: string = "main";
</script>

<main class={className}>
<svelte:element this={element} class={`card ${className}`}>
<slot />
</main>
</svelte:element>

<style>
main {
.card {
padding: 2rem;
background-color: var(--white);
border: 1px solid var(--gray-300);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@
padding: 1rem;
background-color: var(--white);
border-right: 1px solid var(--gray-300);
flex-shrink: 0;
}
ul {
Expand Down
11 changes: 8 additions & 3 deletions web/src/routes/backOffice/components/topbar/TopBar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@
import EmployeeMenu from "./EmployeeMenu.svelte";
</script>

<div class="top-bar">
<nav>
<Link to={BackOfficeRoutes.DASHBOARD}>
<div class="logo-container">
<Logo />
<h1>EcoMap</h1>
</div>
</Link>
<EmployeeMenu />
</div>
</nav>

<style>
.top-bar {
:root {
--top-bar-height: 4rem;
}
nav {
height: var(--top-bar-height);
display: flex;
justify-content: space-between;
justify-items: center;
Expand Down
67 changes: 66 additions & 1 deletion web/src/routes/backOffice/dashboard/Dashboard.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,70 @@
<script lang="ts">
import ecomapHttpClient from "../../../lib/clients/ecomap/http";
import { t } from "../../../lib/utils/i8n";
import { getBatchPaginatedResponse } from "../../../lib/utils/request";
import ContainersAdded from "./partials/ContainersAdded.svelte";
import ContainersByCategory from "./partials/ContainersByCategory.svelte";
import ContainersByMunicipality from "./partials/ContainersByMunicipality.svelte";
import TruckAmount from "./partials/TruckAmount.svelte";
import WarehouseAmount from "./partials/WarehouseAmount.svelte";
import ActiveEmployees from "./partials/ActiveEmployees.svelte";
/**
* Retrieves the containers to be displayed in the charts.
* @returns Containers.
*/
async function getContainers() {
const containers = await getBatchPaginatedResponse(
async (limit, offset) => {
const res = await ecomapHttpClient.GET("/containers", {
params: {
query: {
offset,
limit,
sort: "createdAt",
order: "asc",
},
},
});
if (res.error) {
return { total: 0, items: [] };
}
return { total: res.data.total, items: res.data.containers };
},
);
return containers;
}
let containersPromise = getContainers();
</script>

<main>{$t("dashboard")}</main>
<main class="page-layout">
<h1>{$t("dashboard")}</h1>
<div class="dashboard-content">
<ActiveEmployees />
<WarehouseAmount />
<TruckAmount />
<ContainersAdded {containersPromise} />
<ContainersByCategory {containersPromise} />
<ContainersByMunicipality {containersPromise} />
</div>
</main>

<style>
h1 {
font: var(--text-2xl-semibold);
}
.dashboard-content {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas:
"activeEmployees warehouseAmount truckAmount"
"containersAdded containersAdded containersByCategory"
"containersByMunicipality containersByMunicipality containersByMunicipality";
gap: 1rem;
}
</style>
Loading

0 comments on commit 5e08c9c

Please sign in to comment.