From faa9788e16badf95462e8286751b04f8ccc72e12 Mon Sep 17 00:00:00 2001
From: Akseli Kolari <33838340+Akzuu@users.noreply.github.com>
Date: Sun, 19 Nov 2023 08:18:54 +0200
Subject: [PATCH] Feat/71 (#85)
---
package-lock.json | 29 ++-
package.json | 3 +-
.../DivingCylinderSetList.tsx | 12 +-
src/components/FillEvents/ListFillEvents.tsx | 105 ++++++-----
src/components/common/Table.tsx | 166 -----------------
.../common/Table/CommonTable.module.scss | 80 ++++++++
src/components/common/Table/CommonTable.tsx | 176 ++++++++++++++++++
src/styles/commonTable/commonTable.css | 18 --
src/styles/commonTable/commonTable.sass | 22 ---
src/variables.scss | 3 +
10 files changed, 355 insertions(+), 259 deletions(-)
delete mode 100644 src/components/common/Table.tsx
create mode 100644 src/components/common/Table/CommonTable.module.scss
create mode 100644 src/components/common/Table/CommonTable.tsx
delete mode 100644 src/styles/commonTable/commonTable.css
delete mode 100644 src/styles/commonTable/commonTable.sass
diff --git a/package-lock.json b/package-lock.json
index 348a173..1589571 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,6 +20,7 @@
"@types/react-dom": "^18.0.6",
"axios": "^1.1.3",
"bootstrap": "^5.2.1",
+ "date-fns": "^2.30.0",
"formik": "^2.2.9",
"google-libphonenumber": "^3.2.32",
"react": "^18.2.0",
@@ -1902,11 +1903,11 @@
"integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
},
"node_modules/@babel/runtime": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.0.tgz",
- "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==",
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
+ "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
"dependencies": {
- "regenerator-runtime": "^0.13.4"
+ "regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
@@ -1924,6 +1925,11 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/runtime/node_modules/regenerator-runtime": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
+ "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
+ },
"node_modules/@babel/template": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
@@ -6514,6 +6520,21 @@
"node": ">=10"
}
},
+ "node_modules/date-fns": {
+ "version": "2.30.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+ "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+ "dependencies": {
+ "@babel/runtime": "^7.21.0"
+ },
+ "engines": {
+ "node": ">=0.11"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
+ },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
diff --git a/package.json b/package.json
index cc038fa..445a4a4 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"@types/react-dom": "^18.0.6",
"axios": "^1.1.3",
"bootstrap": "^5.2.1",
+ "date-fns": "^2.30.0",
"formik": "^2.2.9",
"google-libphonenumber": "^3.2.32",
"react": "^18.2.0",
@@ -64,11 +65,11 @@
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"eslint": "^8.23.0",
- "eslint-plugin-react-hooks": "^4.6.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-standard-with-typescript": "^23.0.0",
"eslint-plugin-n": "^15.3.0",
"eslint-plugin-promise": "^6.1.0",
+ "eslint-plugin-react-hooks": "^4.6.0",
"husky": "^8.0.1",
"lint-staged": "^13.0.3",
"prettier": "^2.7.1",
diff --git a/src/components/DivingCylinderSet/DivingCylinderSetList.tsx b/src/components/DivingCylinderSet/DivingCylinderSetList.tsx
index 313e36e..2fb1112 100644
--- a/src/components/DivingCylinderSet/DivingCylinderSetList.tsx
+++ b/src/components/DivingCylinderSet/DivingCylinderSetList.tsx
@@ -9,26 +9,36 @@ import { archiveDivingCylinderSet } from '../../lib/apiRequests/divingCylinderSe
import { useDivingCylinderQuery } from '../../lib/queries/divingCylinderQuery';
import { DIVING_CYLINDER_SETS_QUERY_KEY } from '../../lib/queries/queryKeys';
import { getUserIdFromAccessToken } from '../../lib/utils';
-import { CommonTable, TableColumn, TableRow } from '../common/Table';
+import {
+ CommonTable,
+ TableColumn,
+ TableRow,
+} from '../common/Table/CommonTable';
const DIVING_CYLINDER_SET_COLUMNS: TableColumn[] = [
{
title: 'Nimi',
+ shortTitle: 'Nimi',
},
{
title: 'Koko (l)',
+ shortTitle: 'l',
},
{
title: 'Materiaali',
+ shortTitle: 'Mat',
},
{
title: 'Suurin täyttöpaine (bar)',
+ shortTitle: 'bar',
},
{
title: 'Sarjanumero',
+ shortTitle: 'SN',
},
{
title: 'Katsastusvuosi',
+ shortTitle: 'KV',
},
];
diff --git a/src/components/FillEvents/ListFillEvents.tsx b/src/components/FillEvents/ListFillEvents.tsx
index b44b805..6fd7006 100644
--- a/src/components/FillEvents/ListFillEvents.tsx
+++ b/src/components/FillEvents/ListFillEvents.tsx
@@ -1,58 +1,69 @@
+import format from 'date-fns/format';
import { useFillEventQuery } from '../../lib/queries/FillEventQuery';
-import { FillEvent } from '../../interfaces/FillEvent';
import { formatEurCentsToEur } from '../../lib/utils';
+import {
+ CommonTable,
+ TableColumn,
+ TableRow,
+} from '../common/Table/CommonTable';
+import { useMemo } from 'react';
-const FillEventRow = ({
- data,
- index,
-}: {
- data: FillEvent;
- index: number;
-}): JSX.Element => {
- return (
-
- {data.createdAt} |
- {data.cylinderSetName} |
- {data.gasMixture} |
- {data.description} |
- {formatEurCentsToEur(data.price)} |
-
- );
-};
+const FILL_EVENT_COLUMNS: TableColumn[] = [
+ {
+ title: 'Päivämäärä',
+ shortTitle: 'Pvm',
+ },
+ {
+ title: 'Pullosetti',
+ shortTitle: 'PS',
+ },
+ {
+ title: 'Kaasuseos',
+ shortTitle: 'KS',
+ },
+ {
+ title: 'Lisätiedot',
+ shortTitle: 'LT',
+ },
+ {
+ title: 'Hinta (€)',
+ shortTitle: '€',
+ },
+];
-export const ListFillEvents = (): JSX.Element => {
- const fillEvents: FillEvent[] = useFillEventQuery().data ?? [];
+const dateFormatter = (date: string): string =>
+ format(new Date(date), 'd.MM.yy');
+export const ListFillEvents = (): JSX.Element => {
+ const { data: fillEvents } = useFillEventQuery();
+ const rows: TableRow[] = useMemo(
+ () =>
+ fillEvents?.map((fillEvent) => ({
+ id: fillEvent.id,
+ mainRow: [
+ dateFormatter(fillEvent.createdAt),
+ fillEvent.cylinderSetName,
+ fillEvent.gasMixture,
+ fillEvent.description,
+ formatEurCentsToEur(fillEvent.price),
+ ],
+ })) ?? [],
+ [fillEvents]
+ );
return (
-
-
Täyttöhistoria
-
-
Täyttöjen hinta yhteensä
-
- {formatEurCentsToEur(
- fillEvents.reduce((acc, fillEvent) => acc + fillEvent.price, 0)
- )}{' '}
- €
-
-
+
+
Täyttöhistoria
+
+ Täyttöjen hinta yhteensä:{' '}
+ {formatEurCentsToEur(
+ fillEvents?.reduce((acc, fillEvent) => acc + fillEvent.price, 0) ??
+ 0
+ )}{' '}
+ €
+
-
-
-
- Päivämäärä |
- pullosetti |
- kaasuseos |
- lisätiedot |
- hinta (€) |
-
-
-
- {fillEvents.map((fillEvent, index) => (
-
- ))}
-
-
+
);
};
diff --git a/src/components/common/Table.tsx b/src/components/common/Table.tsx
deleted file mode 100644
index 0381913..0000000
--- a/src/components/common/Table.tsx
+++ /dev/null
@@ -1,166 +0,0 @@
-import React, { useCallback } from 'react';
-import { BsPencil, BsTrash } from 'react-icons/bs';
-import '../../styles/commonTable/commonTable.css';
-import { IconButton, IconButtonProps } from './Buttons';
-
-type Row = Array
;
-
-export type TableColumn = {
- title: string;
-};
-
-export type TableRow = {
- id: string;
- mainRow: Row;
- childRows?: Row[];
-};
-
-type CommonTableProps = {
- columns: TableColumn[];
- rows: TableRow[];
- includeRowNumber?: boolean;
- includeEditButton?: boolean;
- includeDeleteButton?: boolean;
- onRowDelete?: (id: string) => void;
-};
-
-const IconButtonCell: React.FC = ({
- onClick,
- icon,
-}): JSX.Element => {
- return (
-
-
- |
- );
-};
-
-/**
- * Common table element which can be used in a number of situations.
- * HOX Row length MUST ALWAYS match the length of columns! Otherwise,
- * the styling will break! Empty values can be indicated by using null
- */
-export const CommonTable: React.FC = ({
- columns,
- rows,
- includeDeleteButton = false,
- includeEditButton = false,
- includeRowNumber = false,
- onRowDelete,
-}): JSX.Element => {
- const handleEditButtonClick = useCallback(() => {
- // TODO
- }, []);
-
- const handleDeleteButtonClick = useCallback(
- (id: string) => {
- onRowDelete?.(id);
- },
- [onRowDelete]
- );
-
- return (
-
-
-
- {includeRowNumber ? (
-
- #
- |
- ) : null}
- {columns.map((column) => (
-
- {column.title}
- |
- ))}
- {includeEditButton ? (
-
- Muokkaa
- |
- ) : null}
- {includeDeleteButton ? (
-
- Poista
- |
- ) : null}
-
-
-
- {rows.map((row, index) => (
-
-
- {includeRowNumber ? (
-
- {index + 1}
- |
- ) : null}
-
- {row.mainRow.map((value, valueIndex) => (
-
- {value}
- |
- ))}
-
- {includeEditButton ? (
- }
- onClick={handleEditButtonClick}
- />
- ) : null}
- {includeDeleteButton ? (
- }
- onClick={() => handleDeleteButtonClick(row.id)}
- />
- ) : null}
-
- {/* Does the row have "child" rows */}
- {row.childRows?.map((childRow, childRowIndex) => (
-
- {includeRowNumber ? (
-
- {index + 1}.{childRowIndex + 1}
- |
- ) : null}
- {childRow.map((value, valueIndex) => (
-
- {value}
- |
- ))}
- {includeEditButton ? (
- |
- ) : null}
- {includeDeleteButton ? (
- |
- ) : null}
-
- ))}
-
- ))}
-
-
- );
-};
diff --git a/src/components/common/Table/CommonTable.module.scss b/src/components/common/Table/CommonTable.module.scss
new file mode 100644
index 0000000..b96bcd8
--- /dev/null
+++ b/src/components/common/Table/CommonTable.module.scss
@@ -0,0 +1,80 @@
+@import '../../../variables.scss';
+
+.noBackground:not(:hover) {
+ background-color: rgba(0, 0, 0, 0) !important;
+ border-color: rgba(0, 0, 0, 0) !important;
+}
+
+.content {
+ box-sizing: border-box;
+ background: $white;
+ border-radius: 8px;
+ box-shadow: 0px 4px 10px 2px rgba(0, 0, 0, 0.1);
+ display: flex;
+ overflow: auto;
+ width: 100%;
+}
+
+table {
+ width: 100%;
+
+ thead {
+ background-color: $timberwolf;
+ }
+
+ .evenRow {
+ background-color: $ghost-white;
+ }
+
+ .oddRow {
+ background-color: $white;
+ }
+
+ tr {
+ box-sizing: border-box;
+ }
+
+ th {
+ padding: 0.5rem 1rem;
+
+ span {
+ &:first-child {
+ display: inline;
+ }
+ &:last-child {
+ display: none;
+ }
+ }
+ }
+
+ td {
+ border: 1px solid $timberwolf;
+ padding: 0 1rem;
+ }
+}
+
+@media (max-width: 780px) {
+ h1 {
+ font-size: 1.5rem;
+ width: 50%;
+ }
+ h2 {
+ font-size: 1.25rem;
+ width: 50%;
+ }
+
+ table {
+ th {
+ padding: 0.25rem 0.5rem;
+
+ span {
+ &:first-child {
+ display: none;
+ }
+ &:last-child {
+ display: inline;
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/common/Table/CommonTable.tsx b/src/components/common/Table/CommonTable.tsx
new file mode 100644
index 0000000..8e71c5b
--- /dev/null
+++ b/src/components/common/Table/CommonTable.tsx
@@ -0,0 +1,176 @@
+import React, { useCallback } from 'react';
+import { BsPencil, BsTrash } from 'react-icons/bs';
+import { IconButton, IconButtonProps } from '../Buttons';
+import styles from './CommonTable.module.scss';
+
+type Row = Array;
+
+export type TableColumn = {
+ title: string;
+ shortTitle: string;
+};
+
+export type TableRow = {
+ id: string;
+ mainRow: Row;
+ childRows?: Row[];
+ formatter?: () => string;
+};
+
+type CommonTableProps = {
+ columns: TableColumn[];
+ rows: TableRow[];
+ includeRowNumber?: boolean;
+ includeEditButton?: boolean;
+ includeDeleteButton?: boolean;
+ onRowDelete?: (id: string) => void;
+};
+
+const IconButtonCell: React.FC = ({
+ onClick,
+ icon,
+}): JSX.Element => {
+ return (
+
+
+ |
+ );
+};
+
+/**
+ * Common table element which can be used in a number of situations.
+ * HOX Row length MUST ALWAYS match the length of columns! Otherwise,
+ * the styling will break! Empty values can be indicated by using null
+ */
+export const CommonTable: React.FC = ({
+ columns,
+ rows,
+ includeDeleteButton = false,
+ includeEditButton = false,
+ includeRowNumber = false,
+ onRowDelete,
+}): JSX.Element => {
+ const handleEditButtonClick = useCallback(() => {
+ // TODO
+ }, []);
+
+ const handleDeleteButtonClick = useCallback(
+ (id: string) => {
+ onRowDelete?.(id);
+ },
+ [onRowDelete]
+ );
+
+ return (
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+
+
+
+
+ {includeRowNumber ? (
+
+ #
+ |
+ ) : null}
+ {columns.map((column) => (
+
+ {column.title}
+ {column.shortTitle}
+ |
+ ))}
+ {includeEditButton ? (
+
+ Muokkaa
+ |
+ ) : null}
+ {includeDeleteButton ? (
+
+ Poista
+ |
+ ) : null}
+
+
+
+ {rows.map((row, index) => (
+
+
+ {includeRowNumber ? (
+
+ {index + 1}
+ |
+ ) : null}
+
+ {row.mainRow.map((value, valueIndex) => (
+
+ {value}
+ |
+ ))}
+
+ {includeEditButton ? (
+ }
+ onClick={handleEditButtonClick}
+ />
+ ) : null}
+ {includeDeleteButton ? (
+ }
+ onClick={() => handleDeleteButtonClick(row.id)}
+ />
+ ) : null}
+
+ {/* Does the row have "child" rows */}
+ {row.childRows?.map((childRow, childRowIndex) => (
+
+ {includeRowNumber ? (
+
+ {index + 1}.{childRowIndex + 1}
+ |
+ ) : null}
+ {childRow.map((value, valueIndex) => (
+
+ {value}
+ |
+ ))}
+ {includeEditButton ? (
+ |
+ ) : null}
+ {includeDeleteButton ? (
+ |
+ ) : null}
+
+ ))}
+
+ ))}
+
+
+
+ );
+};
diff --git a/src/styles/commonTable/commonTable.css b/src/styles/commonTable/commonTable.css
deleted file mode 100644
index 4c726d3..0000000
--- a/src/styles/commonTable/commonTable.css
+++ /dev/null
@@ -1,18 +0,0 @@
-.no-background:not(:hover) {
- background-color: rgba(0, 0, 0, 0) !important;
- border-color: rgba(0, 0, 0, 0) !important;
-}
-
-.table {
- border: 1px solid #D6D6D6;
- white-space: nowrap;
-}
-.table .tableHead {
- background-color: #D9E1E9;
-}
-.table .evenRow {
- background-color: rgba(217, 225, 233, 0.2784313725);
-}
-.table .oddRow {
- background-color: #FFFFFF;
-}
diff --git a/src/styles/commonTable/commonTable.sass b/src/styles/commonTable/commonTable.sass
deleted file mode 100644
index 2c3f4ab..0000000
--- a/src/styles/commonTable/commonTable.sass
+++ /dev/null
@@ -1,22 +0,0 @@
-$transparentColor: rgba(0, 0, 0, 0)
-$evenRow: #D9E1E947
-$oddRow: #FFFFFF
-$titleBarBlue: #D9E1E9
-$borderColor: #D6D6D6
-
-.no-background:not(:hover)
- background-color: $transparentColor !important
- border-color: $transparentColor !important
-
-.table
- border: 1px solid $borderColor
- white-space: nowrap
-
- .tableHead
- background-color: $titleBarBlue
-
- .evenRow
- background-color: $evenRow
-
- .oddRow
- background-color: $oddRow
diff --git a/src/variables.scss b/src/variables.scss
index 50f041e..8f8a063 100644
--- a/src/variables.scss
+++ b/src/variables.scss
@@ -1,3 +1,4 @@
+$aluminium: #d6d6d6;
$black: #000000;
$blue-charcoal: #1b2631;
$dark-blue: #003143;
@@ -6,3 +7,5 @@ $blue-hover: #405c7a;
$grey: #c3c3c3;
$white: #ffffff;
$white-smoke: #f4f4f4;
+$ghost-white: #d9e1e947;
+$timberwolf: #d9e1e9;