diff options
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/_app.tsx | 22 | ||||
| -rw-r--r-- | src/pages/index.tsx | 191 |
2 files changed, 0 insertions, 213 deletions
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx deleted file mode 100644 index 139eaeb..0000000 --- a/src/pages/_app.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import "semantic-ui-css/semantic.min.css"; -import "../styles/globals.css"; -import type { AppProps } from "next/app"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import React from "react"; - -const queryClient = new QueryClient(); - -function MyApp({ Component, pageProps }: AppProps) { - return ( - <QueryClientProvider client={queryClient}> - <Component {...pageProps} /> - {process.env.APP_ENV === "development" ? ( - <div style={{ textAlign: "center", marginTop: "14px" }}> - <a href="/q/dev/">Visit Quarkus dev page</a> - </div> - ) : undefined} - </QueryClientProvider> - ); -} - -export default MyApp; diff --git a/src/pages/index.tsx b/src/pages/index.tsx deleted file mode 100644 index 6ba4d3d..0000000 --- a/src/pages/index.tsx +++ /dev/null @@ -1,191 +0,0 @@ -import type { NextPage } from "next"; -import Head from "next/head"; -import { List } from "immutable"; -import { - Header, - Table, - Message, - Container, - Pagination, - Input, - Grid, -} from "semantic-ui-react"; - -import styles from "../styles/Home.module.css"; -import React, { useMemo, useState } from "react"; -import AddItem from "../components/add-item"; -import { - getGetItemsQueryKey, - useGetItems, - usePostItemsHook, -} from "../util/pantry-item-resource"; -import { PantryItem } from "../model"; -import { useMutation, useQueryClient } from "@tanstack/react-query"; - -const ENTRIES_PER_PAGE = Number(process.env.ENTRIES_PER_PAGE ?? "10"); - -interface SortStateProps { - field: keyof PantryItem; - order: "ascending" | "descending"; -} - -const Home: NextPage = () => { - const { data, error } = useGetItems(); - const postItems = usePostItemsHook(); - const queryClient = useQueryClient(); - const { mutate } = useMutation(postItems, { - onSuccess: async (item) => { - queryClient.setQueryData( - getGetItemsQueryKey(), - (data ?? []).concat(item) - ); - }, - }); - const [activePage, setActivePage] = useState(1); - const [searchState, setSearchState] = useState<string>(""); - const [sortState, setSortState] = useState<SortStateProps>({ - field: "name", - order: "ascending", - }); - - const hasEntries = useMemo( - () => error === null && (data === undefined || data.length > 0), - [error, data] - ); - const entries = useMemo(() => { - const list = List<PantryItem>(data); - - // case insensitive filter - const filterValue = searchState.trim().toUpperCase(); - const filterList: List<PantryItem> = - filterValue !== "" - ? list.filter( - (item) => - item.name?.toUpperCase().includes(filterValue) || - item.description?.toUpperCase().includes(filterValue) || - item.quantityUnitType?.toUpperCase().includes(filterValue) - ) - : list; - - // case insensitive sort - const sorted = filterList.sortBy((item) => - item[sortState.field]?.toString().toUpperCase() - ); - - return sortState.order === "ascending" ? sorted : sorted.reverse(); - }, [data, sortState, searchState]); - const handleSortChange = (field: keyof PantryItem) => { - setSortState((state) => - state.field === field - ? { - ...state, - order: state.order === "ascending" ? "descending" : "ascending", - } - : { field: field, order: "ascending" } - ); - }; - - return ( - <Container className={styles.container}> - <Head> - <title>Pantry</title> - <meta - name="description" - content="Meal planning with inventory management" - /> - <link rel="icon" href="/favicon.ico" /> - </Head> - - <Header as="h1" className="title"> - Pantry - </Header> - - <AddItem addItem={(newItem) => Promise.resolve(mutate(newItem))} /> - <Message error={error !== null} attached hidden={hasEntries}> - {error !== null - ? error.message !== undefined - ? `Network error occurred: ${error.message}` - : "Unknown network error occurred" - : "Nothing's in the pantry at the moment!"} - </Message> - <Table sortable attached="bottom"> - <Table.Header> - <Table.Row> - <Table.HeaderCell - sorted={sortState.field === "name" ? sortState.order : undefined} - onClick={() => handleSortChange("name")} - > - Name - </Table.HeaderCell> - <Table.HeaderCell - sorted={ - sortState.field === "description" ? sortState.order : undefined - } - onClick={() => handleSortChange("description")} - > - Description - </Table.HeaderCell> - <Table.HeaderCell - sorted={ - sortState.field === "quantity" ? sortState.order : undefined - } - onClick={() => handleSortChange("quantity")} - > - Quantity - </Table.HeaderCell> - </Table.Row> - </Table.Header> - <Table.Body> - {entries - .valueSeq() - .slice( - (activePage - 1) * ENTRIES_PER_PAGE, - activePage * ENTRIES_PER_PAGE - ) - .map((item: PantryItem) => ( - <Table.Row key={item.id}> - <Table.Cell>{item.name}</Table.Cell> - <Table.Cell> - {item.description === "" ? "—" : item.description} - </Table.Cell> - <Table.Cell> - {item.quantity} {item.quantityUnitType} - </Table.Cell> - </Table.Row> - ))} - </Table.Body> - <Table.Footer> - <Table.Row> - <Table.HeaderCell colspan="3"> - <Grid> - <Grid.Column width="4" /> - <Grid.Column width="8" className="paginate-container"> - <Pagination - activePage={activePage} - onPageChange={(_, { activePage }) => - setActivePage(Number(activePage ?? 1)) - } - totalPages={Math.max( - 1, - Math.ceil(entries.size / ENTRIES_PER_PAGE) - )} - /> - </Grid.Column> - <Grid.Column floated="right" width="4"> - <Input - value={searchState} - onChange={(_, { value }) => setSearchState(value)} - placeholder="Search..." - icon="search" - /> - </Grid.Column> - </Grid> - </Table.HeaderCell> - </Table.Row> - </Table.Footer> - </Table> - </Container> - ); -}; - -export default Home; |
