diff --git a/front/package.json b/front/package.json
index 2a320aa..84aefe3 100644
--- a/front/package.json
+++ b/front/package.json
@@ -10,10 +10,12 @@
},
"dependencies": {
"ky": "^1.7.2",
- "preact": "^10.24.3"
+ "preact": "^10.24.3",
+ "react-infinite-scroller": "^1.2.6"
},
"devDependencies": {
"@preact/preset-vite": "^2.9.1",
+ "@types/react-infinite-scroller": "^1.2.5",
"sass": "^1.80.6",
"sass-embedded": "^1.80.6",
"typescript": "~5.6.2",
diff --git a/front/src/components/Posts.module.scss b/front/src/components/Posts.module.scss
index 0da5507..3d31071 100644
--- a/front/src/components/Posts.module.scss
+++ b/front/src/components/Posts.module.scss
@@ -1,3 +1,10 @@
.posts {
- display: block;
+ display: flex;
+ flex-direction: column;
+
+ li {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ }
}
\ No newline at end of file
diff --git a/front/src/components/Posts.tsx b/front/src/components/Posts.tsx
index eceb248..12431a7 100644
--- a/front/src/components/Posts.tsx
+++ b/front/src/components/Posts.tsx
@@ -1,13 +1,34 @@
+import { ComponentChildren, toChildArray } from "preact";
import { DataRow } from "../api/DataRow";
import style from './Posts.module.scss';
import { Post } from "./display/Post";
-export type PostsProps = { rows: DataRow[] };
+export type PostsProps = {
+ rows: DataRow[],
+ checked?: boolean,
+ onSelectChange?: (row: DataRow) => void
+};
+
+export function Posts(props: PostsProps) {
+
+ function onChange(row: DataRow) {
+ if (props.onSelectChange) props.onSelectChange(row)
+ }
-export function Posts({ rows }: PostsProps) {
return (
-
- { rows.map(row =>
) }
-
+
);
}
\ No newline at end of file
diff --git a/front/src/pages/index.module.scss b/front/src/pages/index.module.scss
index 158402e..7058559 100644
--- a/front/src/pages/index.module.scss
+++ b/front/src/pages/index.module.scss
@@ -1,4 +1,7 @@
.index {
+ .selection {
+ background: antiquewhite;
+ }
.paginator {
border-bottom: 1px solid black;
padding-bottom: 1rem;
diff --git a/front/src/pages/index.tsx b/front/src/pages/index.tsx
index 0c4f824..6010e6a 100644
--- a/front/src/pages/index.tsx
+++ b/front/src/pages/index.tsx
@@ -1,63 +1,70 @@
-import { useEffect, useState } from "preact/hooks";
+import { useCallback, useState } from "preact/hooks";
import { DataRow } from "../api/DataRow";
import style from './index.module.scss';
import { Posts } from "../components/Posts";
-import { Paginator } from "../components/display/Paginator";
-const cachedPages: {
- [ key: number ]: DataRow[]
-} = {};
+import InfiniteScroller from 'react-infinite-scroller';
-let firstRender = true;
+// let page = -1;
export function Index() {
const [ data, setData ] = useState(null as null | DataRow[]);
- const [ page, setPage ] = useState(NaN);
- const [ pageBlocked, setPageBlocked ] = useState(false);
+ const [ selected, setSelected ] = useState(null as null | DataRow[]);
- async function goToPage(newPage: number) {
- if (newPage < 0) newPage = 0;
- if (pageBlocked) return;
+ const [ hasMore, setHasMore ] = useState(true);
+ const [ fetching, setFetching ] = useState(false);
- let newData = null as DataRow[] | null;
- if (cachedPages[newPage]) {
- newData = cachedPages[newPage];
- } else {
- setData(null);
- }
+ const fetchMore = useCallback(
+ async function(_page: number) {
+ if (fetching) return;
- setPage(newPage);
- setPageBlocked(true);
- try {
- newData = await DataRow.find({
- page: newPage
+ setFetching(true);
+ await new Promise(r => setTimeout(r, 1000));
+ const newData = await DataRow.find({
+ page: data ? Math.floor(data.length / 20) : 0
});
- } catch (_) {
- return setPageBlocked(false)
- }
+ setData([ ...data ?? [], ...newData ]);
+ setHasMore(newData.length === 20);
+ setFetching(false);
+ },
+ [ fetching, hasMore ]
+ );
- if (newData === undefined) {
- newData = [] as DataRow[];
+ function select(row: DataRow) {
+ console.log(row);
+ if (data) {
+ if (data.indexOf(row) == -1) throw new Error('Selected element that does not exist');
+ setSelected([ ...selected ?? [], row ])
+ setData(data)
}
-
- cachedPages[newPage] = newData;
- setPageBlocked(false);
- setData(newData);
}
- if (firstRender) {
- goToPage(0);
- firstRender = false;
- }
-
return (
-
+
{
- data
- ?
- :
loading . . .
+ selected
+ ?
+
+ : null
}
+
+
loading . . .}
+ useWindow={false}
+ >
+ {
+ data
+ ? selected ? selected?.indexOf(x) === -1 : true)} onSelectChange={select} />
+ : <>>
+ }
+
)
}
\ No newline at end of file
diff --git a/front/yarn.lock b/front/yarn.lock
index 54ed43e..d84267f 100644
--- a/front/yarn.lock
+++ b/front/yarn.lock
@@ -569,6 +569,26 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
+"@types/prop-types@*":
+ version "15.7.13"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.13.tgz#2af91918ee12d9d32914feb13f5326658461b451"
+ integrity sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==
+
+"@types/react-infinite-scroller@^1.2.5":
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/@types/react-infinite-scroller/-/react-infinite-scroller-1.2.5.tgz#7c770be59465f3aaa1b86377d792d52de5e74047"
+ integrity sha512-fJU1jhMgoL6NJFrqTM0Ob7tnd2sQWGxe2ESwiU6FZWbJK/VO/Er5+AOhc+e2zbT0dk5pLygqctsulOLJ8xnSzw==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react@*":
+ version "18.3.12"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.12.tgz#99419f182ccd69151813b7ee24b792fe08774f60"
+ integrity sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==
+ dependencies:
+ "@types/prop-types" "*"
+ csstype "^3.0.2"
+
babel-plugin-transform-hook-names@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-hook-names/-/babel-plugin-transform-hook-names-1.0.2.tgz#0d75c2d78e8bbcdb258241131562b9cf07f010f3"
@@ -639,6 +659,11 @@ css-what@^6.1.0:
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
+csstype@^3.0.2:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
+ integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
+
debug@^4.1.0, debug@^4.3.1, debug@^4.3.4:
version "4.3.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
@@ -784,7 +809,7 @@ is-number@^7.0.0:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
-js-tokens@^4.0.0:
+"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
@@ -809,6 +834,13 @@ ky@^1.7.2:
resolved "https://registry.yarnpkg.com/ky/-/ky-1.7.2.tgz#b97d9b997ba51ff1e152f0815d3d27b86513eb1c"
integrity sha512-OzIvbHKKDpi60TnF9t7UUVAF1B4mcqc02z5PIvrm08Wyb+yOcz63GRvEuVxNT18a9E1SrNouhB4W2NNLeD7Ykg==
+loose-envify@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
+ integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
+ dependencies:
+ js-tokens "^3.0.0 || ^4.0.0"
+
lru-cache@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
@@ -866,6 +898,11 @@ nth-check@^2.0.1:
dependencies:
boolbase "^1.0.0"
+object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+ integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
+
picocolors@^1.0.0, picocolors@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
@@ -890,6 +927,27 @@ preact@^10.24.3:
resolved "https://registry.yarnpkg.com/preact/-/preact-10.24.3.tgz#086386bd47071e3b45410ef20844c21e23828f64"
integrity sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==
+prop-types@^15.5.8:
+ version "15.8.1"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
+ integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
+ dependencies:
+ loose-envify "^1.4.0"
+ object-assign "^4.1.1"
+ react-is "^16.13.1"
+
+react-infinite-scroller@^1.2.6:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/react-infinite-scroller/-/react-infinite-scroller-1.2.6.tgz#8b80233226dc753a597a0eb52621247f49b15f18"
+ integrity sha512-mGdMyOD00YArJ1S1F3TVU9y4fGSfVVl6p5gh/Vt4u99CJOptfVu/q5V/Wlle72TMgYlBwIhbxK5wF0C/R33PXQ==
+ dependencies:
+ prop-types "^15.5.8"
+
+react-is@^16.13.1:
+ version "16.13.1"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
+ integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+
readdirp@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.2.tgz#388fccb8b75665da3abffe2d8f8ed59fe74c230a"