aboutsummaryrefslogtreecommitdiff
path: root/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/_app.tsx22
-rw-r--r--src/pages/index.tsx191
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;