commit
d5a39aa5f4
13
README.md
13
README.md
@ -11,6 +11,13 @@
|
|||||||
- Multilanguage support
|
- Multilanguage support
|
||||||
- Markdown format for the rich text fields
|
- Markdown format for the rich text fields
|
||||||
|
|
||||||
|
#### [Image Processor](https://github.com/Accords-Library/img.accords-library.com)
|
||||||
|
- Convert the images from the CMS to 4 formats
|
||||||
|
- Small: 512x512, quality 60, .webp
|
||||||
|
- Medium: 1024x1024, quality 75, .webp
|
||||||
|
- Large: 2048x2048, quality 80, .webp
|
||||||
|
- Og: 512x512, quality 60, .jpg
|
||||||
|
|
||||||
#### [Front](https://github.com/Accords-Library/accords-library.com) (this repository)
|
#### [Front](https://github.com/Accords-Library/accords-library.com) (this repository)
|
||||||
|
|
||||||
- Language: [TypeScript](https://www.typescriptlang.org/)
|
- Language: [TypeScript](https://www.typescriptlang.org/)
|
||||||
@ -31,6 +38,12 @@
|
|||||||
- State Management: [React Context](https://reactjs.org/docs/context.html)
|
- State Management: [React Context](https://reactjs.org/docs/context.html)
|
||||||
- Persistent app state using LocalStorage
|
- Persistent app state using LocalStorage
|
||||||
- Support for many screen sizes and resolutions
|
- Support for many screen sizes and resolutions
|
||||||
|
- SSG (Static Site Generation):
|
||||||
|
- The website is built before running in production
|
||||||
|
- Performances are great, and possibility to deploy the app using a CDN
|
||||||
|
- OpenGraph and Metadata
|
||||||
|
- Good defaults for the metadate and OpenGraph properties
|
||||||
|
- Each page can provide the thumbnail, title, description to be used
|
||||||
- Data quality testing
|
- Data quality testing
|
||||||
- Data from the CMS is subject to a battery of tests (about 20 warning types and 40 error types) at build time
|
- Data from the CMS is subject to a battery of tests (about 20 warning types and 40 error types) at build time
|
||||||
- Each warning/error comes with a front-end link to the incriminating element, as well as a link to the CMS to fix it.
|
- Each warning/error comes with a front-end link to the incriminating element, as well as a link to the CMS to fix it.
|
||||||
|
@ -21,7 +21,7 @@ export default function Button(props: ButtonProps): JSX.Element {
|
|||||||
} ${
|
} ${
|
||||||
props.active
|
props.active
|
||||||
? "text-light bg-black drop-shadow-black-lg !border-black cursor-not-allowed"
|
? "text-light bg-black drop-shadow-black-lg !border-black cursor-not-allowed"
|
||||||
: "cursor-pointer hover:text-light hover:bg-dark hover:drop-shadow-shade-lg active:bg-black active:drop-shadow-black-lg active:border-black"
|
: "cursor-pointer hover:text-light hover:bg-dark hover:drop-shadow-shade-lg active:bg-black active:text-light active:drop-shadow-black-lg active:border-black"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
|
@ -4,6 +4,7 @@ import ContentPanel, {
|
|||||||
ContentPanelWidthSizes,
|
ContentPanelWidthSizes,
|
||||||
} from "components/Panels/ContentPanel";
|
} from "components/Panels/ContentPanel";
|
||||||
import {
|
import {
|
||||||
|
GetCurrenciesQuery,
|
||||||
GetLibraryItemsPreviewQuery,
|
GetLibraryItemsPreviewQuery,
|
||||||
GetWebsiteInterfaceQuery,
|
GetWebsiteInterfaceQuery,
|
||||||
} from "graphql/operations-types";
|
} from "graphql/operations-types";
|
||||||
@ -13,7 +14,7 @@ import AppLayout from "components/AppLayout";
|
|||||||
import LibraryItemsPreview from "components/Library/LibraryItemsPreview";
|
import LibraryItemsPreview from "components/Library/LibraryItemsPreview";
|
||||||
import Select from "components/Select";
|
import Select from "components/Select";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { prettyDate, prettyinlineTitle } from "queries/helpers";
|
import { convertPrice, prettyDate, prettyinlineTitle } from "queries/helpers";
|
||||||
import Switch from "components/Switch";
|
import Switch from "components/Switch";
|
||||||
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ type GroupLibraryItems = Map<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
export default function Library(props: LibraryProps): JSX.Element {
|
export default function Library(props: LibraryProps): JSX.Element {
|
||||||
const { langui, items } = props;
|
const { langui, items, currencies } = props;
|
||||||
|
|
||||||
const [showSubitems, setShowSubitems] = useState<boolean>(false);
|
const [showSubitems, setShowSubitems] = useState<boolean>(false);
|
||||||
const [showPrimaryItems, setShowPrimaryItems] = useState<boolean>(true);
|
const [showPrimaryItems, setShowPrimaryItems] = useState<boolean>(true);
|
||||||
@ -40,7 +41,7 @@ export default function Library(props: LibraryProps): JSX.Element {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const [sortedItems, setSortedItem] = useState<LibraryProps["items"]>(
|
const [sortedItems, setSortedItem] = useState<LibraryProps["items"]>(
|
||||||
sortBy(groupingMethod, filteredItems)
|
sortBy(groupingMethod, filteredItems, currencies)
|
||||||
);
|
);
|
||||||
|
|
||||||
const [groups, setGroups] = useState<GroupLibraryItems>(
|
const [groups, setGroups] = useState<GroupLibraryItems>(
|
||||||
@ -54,7 +55,7 @@ export default function Library(props: LibraryProps): JSX.Element {
|
|||||||
}, [showSubitems, items, showPrimaryItems, showSecondaryItems]);
|
}, [showSubitems, items, showPrimaryItems, showSecondaryItems]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSortedItem(sortBy(sortingMethod, filteredItems));
|
setSortedItem(sortBy(sortingMethod, filteredItems, currencies));
|
||||||
}, [filteredItems, sortingMethod]);
|
}, [filteredItems, sortingMethod]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -278,7 +279,8 @@ function filterItems(
|
|||||||
|
|
||||||
function sortBy(
|
function sortBy(
|
||||||
orderByType: number,
|
orderByType: number,
|
||||||
items: LibraryProps["items"]
|
items: LibraryProps["items"],
|
||||||
|
currencies: GetCurrenciesQuery["currencies"]["data"]
|
||||||
): LibraryProps["items"] {
|
): LibraryProps["items"] {
|
||||||
switch (orderByType) {
|
switch (orderByType) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -297,8 +299,12 @@ function sortBy(
|
|||||||
});
|
});
|
||||||
case 1:
|
case 1:
|
||||||
return [...items].sort((a, b) => {
|
return [...items].sort((a, b) => {
|
||||||
const priceA = a.attributes.price ? a.attributes.price.amount : 99999;
|
const priceA = a.attributes.price
|
||||||
const priceB = b.attributes.price ? b.attributes.price.amount : 99999;
|
? convertPrice(a.attributes.price, currencies[0])
|
||||||
|
: 99999;
|
||||||
|
const priceB = b.attributes.price
|
||||||
|
? convertPrice(b.attributes.price, currencies[0])
|
||||||
|
: 99999;
|
||||||
return priceA - priceB;
|
return priceA - priceB;
|
||||||
});
|
});
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -33,10 +33,7 @@ export function prettyPrice(
|
|||||||
let result = "";
|
let result = "";
|
||||||
currencies.map((currency) => {
|
currencies.map((currency) => {
|
||||||
if (currency.attributes.code === targetCurrencyCode) {
|
if (currency.attributes.code === targetCurrencyCode) {
|
||||||
let amountInUSD =
|
const amountInTargetCurrency = convertPrice(pricePicker, currency);
|
||||||
pricePicker.amount * pricePicker.currency.data.attributes.rate_to_usd;
|
|
||||||
let amountInTargetCurrency =
|
|
||||||
amountInUSD / currency.attributes.rate_to_usd;
|
|
||||||
result =
|
result =
|
||||||
currency.attributes.symbol +
|
currency.attributes.symbol +
|
||||||
amountInTargetCurrency.toLocaleString(undefined, {
|
amountInTargetCurrency.toLocaleString(undefined, {
|
||||||
@ -48,6 +45,16 @@ export function prettyPrice(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function convertPrice(
|
||||||
|
pricePicker: GetLibraryItemsPreviewQuery["libraryItems"]["data"][number]["attributes"]["price"],
|
||||||
|
targetCurrency: GetCurrenciesQuery["currencies"]["data"][number]
|
||||||
|
): number {
|
||||||
|
return (
|
||||||
|
(pricePicker.amount * pricePicker.currency.data.attributes.rate_to_usd) /
|
||||||
|
targetCurrency.attributes.rate_to_usd
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function prettySlug(slug?: string, parentSlug?: string): string {
|
export function prettySlug(slug?: string, parentSlug?: string): string {
|
||||||
if (slug) {
|
if (slug) {
|
||||||
if (parentSlug && slug.startsWith(parentSlug))
|
if (parentSlug && slug.startsWith(parentSlug))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user