Skip to content
This repository was archived by the owner on May 24, 2022. It is now read-only.

Commit

Permalink
feat: wishlist paging
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelass committed Sep 29, 2021
1 parent 2055615 commit b758e87
Show file tree
Hide file tree
Showing 41 changed files with 2,574 additions and 1,244 deletions.
24 changes: 22 additions & 2 deletions cypress/integration/common/wishlist/prerequisites.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,37 @@ Given("the wishlist has {int} wishes", function (count) {
});

Given("the wishlist has the following wishes:", function (table) {
const wishes = table.hashes().map(({ body, id, subject, votes }) => {
const hashes = table.hashes();
const wishes = hashes.map(({ body, id, subject, votes }) => {
return {
authorId: 1,
body,
id,
subject,
voted: false,
moderate: "accepted",
votes,
__typename: "Wish",
};
});
this.count = wishes.length;
cy.gql("wishes", { wishes }, { alias: "gql_wishes" });
cy.gql([
{
operationName: "wishes",
data: { wishes },
alias: "gql_wishes",
},
// For aggregated Wishes
// {
// operationName: "aggregateWishes",
// data: {
// aggregateWishes: {
// count: {
// all: hashes.length,
// },
// },
// },
// alias: "gql_aggregateWishes",
// },
]);
});
2 changes: 2 additions & 0 deletions cypress/integration/common/wishlist/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ import { When } from "cypress-cucumber-preprocessor/steps";
When("the user is on the wishlist page", function () {
cy.visit("/wishlist");
cy.wait("@gql_wishes");
// Wait for aggregated Wishes
// cy.wait("@gql_aggregateWishes");
});
16 changes: 9 additions & 7 deletions cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ Cypress.Commands.add("logout", function () {
* @param {object} options Additional options to configure the stub
* @param {object} options.alias The alias of the stub
*/
Cypress.Commands.add("gql", function (operationName, data, { alias }) {
Cypress.Commands.add("gql", function (...operations) {
cy.intercept("POST", Cypress.env("backendUri"), req => {
if (hasOperationName(req, operationName)) {
req.alias = alias;
req.reply(res => {
res.body.data = data;
});
}
operations.forEach(({ operationName, data, alias }) => {
if (hasOperationName(req, operationName)) {
req.alias = alias;
req.reply(res => {
res.body.data = data;
});
}
});
});
});
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@contentful/rich-text-react-renderer": "15.4.0",
"@contentful/rich-text-types": "15.3.6",
"@dekk-app/dekk-backend": "1.11.0",
"@dekk-utils/string-case": "0.1.2",
"@emotion/cache": "11.4.0",
"@emotion/core": "11.0.0",
"@emotion/react": "11.4.1",
Expand Down Expand Up @@ -70,6 +71,7 @@
"sitemap": "7.0.0",
"tslib": "2.3.1",
"use-cookie-consent": "0.1.15",
"use-dark-mode": "2.3.1",
"use-debounce": "7.0.0",
"zustand": "3.5.10"
},
Expand Down
6 changes: 5 additions & 1 deletion public/static/locales/de/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,9 @@
"home": "Home",
"signin": "Anmelden",
"signout": "Abmelden",
"updated-at": "Aktualisiert am"
"updated-at": "Aktualisiert am",
"first-page": "Erste Seite",
"last-page": "Letzte Seite",
"next-page": "Nächste Seite",
"previous-page": "Vorherige Seite"
}
4 changes: 3 additions & 1 deletion public/static/locales/de/wishlist.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@
},
"search-wishes": "Wünsche durchsuchen",
"filter": "Filter",
"hide": "Verstecken",
"pending": "Ausstehend",
"declined": "Abgelehnt",
"accepted": "Akzeptiert",
"tooltip": {
"disabled": "Wünsche mit Stimmen können nicht bearbeitet werden."
},
"add-wish": {
"headline": "Nenne uns deinen Wunsch",
"body": "Als Dankeschön schenken wir dir ein Dekk Pro Konto"
},
"my-wish": "Mein Wunsch"
"my-wish": "Von mir"
}
6 changes: 5 additions & 1 deletion public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,9 @@
"home": "Home",
"signin": "Sign in",
"signout": "Sign out",
"updated-at": "Updated at"
"updated-at": "Updated at",
"first-page": "First page",
"last-page": "Last page",
"next-page": "Next page",
"previous-page": "Previous page"
}
4 changes: 3 additions & 1 deletion public/static/locales/en/wishlist.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@
},
"search-wishes": "Search wishes",
"filter": "Filter",
"hide": "Hide",
"pending": "Pending",
"declined": "Declined",
"accepted": "Accepted",
"tooltip": {
"disabled": "Can't edit wishes with votes."
},
"add-wish": {
"headline": "Tell us your wish",
"body": "As a thank-you we will gift you a Dekk pro account"
},
"my-wish": "My wish"
"my-wish": "Mine"
}
1 change: 1 addition & 0 deletions src/atoms/button/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const StyledButton = styled.button<StyledButtonProps>`
margin: 0;
padding: 0 ${pxToRem(24)};
border: 0;
font-family: inherit;
font-size: ${pxToRem(16)};
font-weight: 600;
line-height: ${pxToRem(24)};
Expand Down
5 changes: 5 additions & 0 deletions src/atoms/icon-button/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ export const StyledIconButton = styled.button`
border-radius: 50%;
background: none;
color: currentColor;
font-family: inherit;
font-size: inherit;
font-weight: 600;
line-height: ${pxToRem(24)};
&:focus {
outline: 0;
}
&[disabled] {
opacity: 0.2;
pointer-events: none;
}
${({ theme }) => css`
Expand Down
5 changes: 5 additions & 0 deletions src/ions/hooks/case/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { objectSnakeToCamel } from "@/ions/utils/object";
import { useMemo } from "react";

export const useObjectSnakeToCamel = <T>(value: Record<string, T>) =>
useMemo(() => objectSnakeToCamel<T>(value), [value]);
81 changes: 81 additions & 0 deletions src/ions/hooks/paging/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { useObjectSnakeToCamel } from "@/ions/hooks/case";
import { useQueryRouter } from "@/ions/hooks/query-router";
import { objectCamelToSnake } from "@/ions/utils/object";
import { decreaseStringNumber, increaseStringNumber, toString } from "@/ions/utils/string";
import { useCallback, useEffect } from "react";

export const usePaging = (length: number, { first = 0, property = "page" }) => {
const { push, query } = useQueryRouter();
const camelObject = useObjectSnakeToCamel<string | string[]>({
[property]: toString(first),
...query,
});

const last = length - 1 + first;
const current = camelObject[property]
? Number.parseInt(camelObject[property] as string, 10)
: first;
// Clamp to max
const clamped = Math.max(Math.min(current, last), first);

useEffect(() => {
if (clamped < current) {
void push(
objectCamelToSnake({
[property]: toString(last),
})
);
}
}, [push, property, current, clamped, last]);

const goTo = useCallback(
(nextState: number) => {
void push(
objectCamelToSnake({
[property]: toString(nextState),
})
);
},
[property, push]
);

const toNext = useCallback(() => {
void push(
objectCamelToSnake({
[property]: increaseStringNumber(camelObject[property] as string),
})
);
}, [property, push, camelObject]);

const toPrevious = useCallback(() => {
void push(
objectCamelToSnake({
[property]: decreaseStringNumber(camelObject[property] as string),
})
);
}, [property, push, camelObject]);

const toFirst = useCallback(() => {
void push(
objectCamelToSnake({
[property]: toString(first),
})
);
}, [property, push, first]);

const toLast = useCallback(() => {
void push(
objectCamelToSnake({
[property]: toString(last),
})
);
}, [property, push, last]);
return {
goTo,
toNext,
toPrevious,
toFirst,
toLast,
current,
};
};
34 changes: 34 additions & 0 deletions src/ions/hooks/query-router/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useRouter } from "next/router";
import { useCallback } from "react";

export const cleanQuery = <T>(query: Record<string, T>) => {
const NextQuery = {};
for (const key in query) {
if (query[key] !== null && query[key] !== undefined) {
NextQuery[key] = query[key];
}
}

return NextQuery;
};

export const useQueryRouter = () => {
const { query, push: routerPush, pathname } = useRouter();
const push = useCallback(
async (nextQuery: Record<string, string>) => {
return routerPush(
{
pathname,
query: cleanQuery({
...query,
...nextQuery,
}),
},
undefined,
{ shallow: true }
);
},
[pathname, routerPush, query]
);
return { push, query, pathname };
};
31 changes: 18 additions & 13 deletions src/ions/hooks/route-loader/index.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,43 @@
import { Router } from "next/router";
import { useEffect, useMemo, useState } from "react";

export interface Options {
shallow?: boolean;
}

export const useRouteLoader = () => {
const [loading, setLoading] = useState(false);
const [loaded, setLoaded] = useState(false);
useEffect(() => {
let timer: number;
const start = () => {
setLoaded(false);
setLoading(true);
const start = (pathname: string, options: Options) => {
if (!options.shallow) {
setLoaded(false);
setLoading(true);
}
};

const end = () => {
setLoading(false);
setLoaded(true);

timer = window.setTimeout(() => {
setLoaded(false);
const end = (pathname: string, options: Options) => {
if (!options.shallow) {
setLoading(false);
}, 250);
setLoaded(true);

timer = window.setTimeout(() => {
setLoaded(false);
}, 250);
}
};

Router.events.on("routeChangeStart", start);
Router.events.on("routeChangeComplete", end);

const unsubscribe = () => {
return () => {
Router.events.off("routeChangeStart", start);
Router.events.off("routeChangeComplete", end);
window.clearTimeout(timer);
setLoaded(false);
setLoading(false);
};

return unsubscribe;
}, []);

return useMemo(() => ({ loaded, loading }), [loaded, loading]);
Expand Down
12 changes: 8 additions & 4 deletions src/ions/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { IconName } from "./types";

export const icons: Record<IconName, string> = {
chevronDown: "M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z",
chevronUp: "M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z",
chevronLeft: "M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z",
chevronRight: "M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z",
check: "M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z",
checkCircleOutline:
"M12 2C6.5 2 2 6.5 2 12S6.5 22 12 22 22 17.5 22 12 17.5 2 12 2M12 20C7.59 20 4 16.41 4 12S7.59 4 12 4 20 7.59 20 12 16.41 20 12 20M16.59 7.58L10 14.17L7.41 11.59L6 13L10 17L18 9L16.59 7.58Z",
chevronDoubleLeft:
"M18.41,7.41L17,6L11,12L17,18L18.41,16.59L13.83,12L18.41,7.41M12.41,7.41L11,6L5,12L11,18L12.41,16.59L7.83,12L12.41,7.41Z",
chevronDoubleRight:
"M5.59,7.41L7,6L13,12L7,18L5.59,16.59L10.17,12L5.59,7.41M11.59,7.41L13,6L19,12L13,18L11.59,16.59L16.17,12L11.59,7.41Z",
chevronDown: "M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z",
chevronLeft: "M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z",
chevronRight: "M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z",
chevronUp: "M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z",
close: "M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z",
delete: "M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z",
edit: "M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z",
Expand Down
2 changes: 2 additions & 0 deletions src/ions/icons/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export type IconName =
| "check"
| "checkCircleOutline"
| "chevronDoubleLeft"
| "chevronDoubleRight"
| "chevronDown"
| "chevronRight"
| "chevronLeft"
Expand Down
Loading

0 comments on commit b758e87

Please sign in to comment.