From c70090e0d5b17f8c73d8c7382ca9861be3ffe5da Mon Sep 17 00:00:00 2001 From: kennyboy55 Date: Wed, 29 May 2024 09:40:39 +0200 Subject: [PATCH] Clean imports, add suggestions and recommendations --- app/components/cards/drink.card.tsx | 1 - app/components/cards/drink.page.tsx | 14 +++ app/components/filters/drink.filter.tsx | 24 +++- app/components/header.tsx | 4 +- app/models/drinks.filter.server.ts | 9 +- app/models/drinks.server.ts | 51 ++++++++ app/models/types.tsx | 2 + app/root.tsx | 12 +- app/routes/_index.tsx | 2 - app/routes/admin/edit/beerstyle.$id.tsx | 4 +- app/routes/admin/edit/beerstyle.tsx | 6 +- app/routes/admin/edit/container.$id.tsx | 5 +- app/routes/admin/edit/container.tsx | 6 +- app/routes/admin/edit/country.$code.tsx | 4 +- app/routes/admin/edit/country.tsx | 6 +- app/routes/admin/edit/manufacturer.tsx | 6 +- app/routes/admin/edit/section.$id.tsx | 4 +- app/routes/admin/edit/section.tsx | 6 +- app/routes/admin/edit/winestyle.$id.tsx | 4 +- app/routes/admin/layout.tsx | 1 - app/routes/admin/manage/checkout.tsx | 1 - app/routes/admin/new/beer.tsx | 4 +- app/routes/admin/new/cocktail.tsx | 4 +- app/routes/admin/new/container.tsx | 7 +- app/routes/admin/new/soda.tsx | 4 +- app/routes/admin/new/wine.tsx | 4 +- app/routes/inventory/beer.$beerslug.tsx | 8 +- .../inventory/cocktail.$cocktailslug.tsx | 8 +- app/routes/inventory/drink.$id.tsx | 10 +- app/routes/inventory/manufacturer.$id.tsx | 14 +-- app/routes/inventory/soda.$sodaslug.tsx | 8 +- app/routes/inventory/stats/route.tsx | 2 +- app/routes/inventory/suggestions/route.tsx | 116 ++++++++++++++++++ app/routes/inventory/wine.$wineslug.tsx | 9 +- app/routes/login.tsx | 14 +-- app/routes/resource/checkouts.tsx | 2 +- app/routes/scan/link.$barcode.tsx | 8 +- app/routes/scan/route.tsx | 7 +- app/utils/arrays.ts | 8 ++ prisma/schema.prisma | 9 ++ schema.zmodel | 10 ++ vite.config.ts | 3 +- 42 files changed, 325 insertions(+), 106 deletions(-) create mode 100644 app/routes/inventory/suggestions/route.tsx create mode 100644 app/utils/arrays.ts diff --git a/app/components/cards/drink.card.tsx b/app/components/cards/drink.card.tsx index ae54446..a234792 100644 --- a/app/components/cards/drink.card.tsx +++ b/app/components/cards/drink.card.tsx @@ -1,5 +1,4 @@ -import { DrinkType } from '@prisma/client'; import { Link } from '@remix-run/react'; import { Badge, Card, ListGroup } from 'react-bootstrap'; import { DrinkComposite, isBeer, isDrinkWithContainers, isDrinkWithManufacturer, isDrinkWithStyle } from '~/models/types'; diff --git a/app/components/cards/drink.page.tsx b/app/components/cards/drink.page.tsx index f33b2e5..0f969f1 100644 --- a/app/components/cards/drink.page.tsx +++ b/app/components/cards/drink.page.tsx @@ -4,9 +4,11 @@ import { Alert, Badge, Button, Col, Container, Image, Row, Table } from 'react-b import { LinkContainer } from 'react-router-bootstrap'; import { ContainerWithSection, DrinkComposite, containerTypeToString, isBeer, isDrinkWithContainersAndSection, isDrinkWithManufacturer, isDrinkWithStyle } from '~/models/types'; import { volume } from '~/utils/conversions'; +import DrinkCard from './drink.card'; interface Arguments { drink: DrinkComposite + recommendations: DrinkComposite[] isAdmin: boolean } @@ -181,6 +183,18 @@ function DrinkPage(arg:Arguments) { ) : ""} + {arg.recommendations.length > 0 ? ( + <> +

Maybe also try

+ + {arg.recommendations.map((drink) => ( + + + + ))} + + + ) : ""} ); } diff --git a/app/components/filters/drink.filter.tsx b/app/components/filters/drink.filter.tsx index f5cce6b..3778a22 100644 --- a/app/components/filters/drink.filter.tsx +++ b/app/components/filters/drink.filter.tsx @@ -1,8 +1,8 @@ import { useSubmit } from '@remix-run/react'; import { BeerStyle, Manufacturer, WineStyle } from '@zenstackhq/runtime/models'; -import { useEffect, useRef, useState } from 'react'; -import { Button, Form, Col, Row } from 'react-bootstrap'; +import { useRef, useState } from 'react'; +import { Form, Col, Row } from 'react-bootstrap'; import ReactSlider from 'react-slider' interface Arguments { @@ -152,11 +152,25 @@ function DrinkFilter(arg : Arguments) { Soda + + ) : ""} diff --git a/app/components/header.tsx b/app/components/header.tsx index a5ed040..615bd83 100644 --- a/app/components/header.tsx +++ b/app/components/header.tsx @@ -1,7 +1,6 @@ import {LinkContainer} from 'react-router-bootstrap' import {Container, Nav, Navbar, NavDropdown} from 'react-bootstrap'; import { User } from '@zenstackhq/runtime/models'; -import { Link } from '@remix-run/react'; import { UserType } from '@prisma/client'; export type HeaderData = {user?: (User)} & {loggedin: boolean}; @@ -38,6 +37,9 @@ function Header(data: Arguments) { Stats + + Suggestions + { showScanButtons ? ( Scan diff --git a/app/models/drinks.filter.server.ts b/app/models/drinks.filter.server.ts index 88ee385..7cbdcc1 100644 --- a/app/models/drinks.filter.server.ts +++ b/app/models/drinks.filter.server.ts @@ -64,7 +64,7 @@ export async function findDrinksFromSearch(searchParams: URLSearchParams) : Prom let where = Object.assign({}, whereBase, {style: {}}); - // Beer styles + // Wine styles if(searchParams.has("winestyle")){ where.style = {id: {in: searchParams.getAll("winestyle").map(Number)}}; } @@ -80,9 +80,12 @@ export async function findDrinksFromSearch(searchParams: URLSearchParams) : Prom let where = whereBase; // Carbonated - if(searchParams.has("carbonated")){ + if(searchParams.get("carbonated") == "1"){ where = Object.assign({}, whereBase, {carbonated: true}); } + if(searchParams.get("carbonated") == "2"){ + where = Object.assign({}, whereBase, {carbonated: false}); + } result = result.concat(await dbe.soda.findMany({ include: {manufacturer: true, containers: {include: {section: true, checkouts: true}}}, @@ -93,7 +96,7 @@ export async function findDrinksFromSearch(searchParams: URLSearchParams) : Prom if(searchParams.has("drink", "Cocktail") || noDrinkSelected){ let where = whereBase; - // Carbonated + // Mix if(searchParams.has("mix")){ where = Object.assign({}, whereBase, {mix: true}); } diff --git a/app/models/drinks.server.ts b/app/models/drinks.server.ts index 182aa95..f341a80 100644 --- a/app/models/drinks.server.ts +++ b/app/models/drinks.server.ts @@ -2,6 +2,8 @@ import { enhance } from "@zenstackhq/runtime"; import { db } from "~/utils/db.server"; import { DrinkType, Manufacturer } from "@prisma/client"; +import { ContainerWithSection, DrinkComposite } from "./types"; +import { shuffleArray } from "~/utils/arrays"; export async function findIdFromSlug(slug:string | undefined) : Promise { if(slug){ @@ -32,5 +34,54 @@ export async function findManufacturersFromSearch(searchParams: URLSearchParams) })); } + return result; +} + +export async function getMostCommonSection(containers : ContainerWithSection[]) : Promise { + + if(containers.length <= 0) return -1; + + const container : ContainerWithSection = containers.reduce((previousValue: ContainerWithSection, currentValue: ContainerWithSection, currentIndex: number, array: ContainerWithSection[]) : ContainerWithSection => { + if(previousValue.inventory > currentValue.inventory) return previousValue; + return currentValue; + }) + + return container.section_id; +} + +export async function findRecommendations(sectionId: number, numRecommendations: number, notId: number) : Promise { + const dbe = enhance(db); + + const drinksWithSameSection = await dbe.drink.findMany({include: {manufacturer: true, containers: true}, where: {id: {not: notId}, containers: {some: {section_id: sectionId}, every: {inventory: {gt: 0}}}}}); + + var result : DrinkComposite[] = []; + + if(drinksWithSameSection.length > 0){ + shuffleArray(drinksWithSameSection); + + if(drinksWithSameSection.length <= numRecommendations){ + result = drinksWithSameSection; + } + else{ + for(var i = 0; i < numRecommendations; i++){ + result.push(drinksWithSameSection[i]) + } + } + } + else { + const completelyRandomDrinks = await dbe.drink.findMany({include: {manufacturer: true, containers: true}, where: {id: {not: notId}, containers: {every: {inventory: {gt: 0}}}}}); + + shuffleArray(completelyRandomDrinks); + + if(completelyRandomDrinks.length <= numRecommendations){ + result = completelyRandomDrinks; + } + else{ + for(var i = 0; i < numRecommendations; i++){ + result.push(completelyRandomDrinks[i]) + } + } + } + return result; } \ No newline at end of file diff --git a/app/models/types.tsx b/app/models/types.tsx index 154d72d..29c9b06 100644 --- a/app/models/types.tsx +++ b/app/models/types.tsx @@ -60,5 +60,7 @@ export function containerTypeToString(type: ContainerType){ return "PET"; case "WineBottle": return "Wine bottle"; + case "Keg": + return "Keg"; } } \ No newline at end of file diff --git a/app/root.tsx b/app/root.tsx index 9d3b1e1..460e3d0 100644 --- a/app/root.tsx +++ b/app/root.tsx @@ -1,13 +1,11 @@ -import type { LinksFunction, LoaderFunctionArgs } from "@remix-run/node"; +import type { LinksFunction } from "@remix-run/node"; import { Links, - Scripts, Outlet, - useRouteError, + Scripts, + ScrollRestoration, isRouteErrorResponse, - json, - useLoaderData, - ScrollRestoration + useRouteError } from "@remix-run/react"; import type { PropsWithChildren } from "react"; @@ -17,9 +15,7 @@ export const links: LinksFunction = () => [ { rel: "stylesheet", href: stylesheet }, ]; -import Header, { HeaderData } from "~/components/header"; import { Col, Container, Row } from "react-bootstrap"; -import { getSession } from "./auth/session"; function Document({ children, diff --git a/app/routes/_index.tsx b/app/routes/_index.tsx index ea68a42..c3e927a 100644 --- a/app/routes/_index.tsx +++ b/app/routes/_index.tsx @@ -1,7 +1,5 @@ -import { UserType } from "@prisma/client"; import type { LoaderFunctionArgs } from "@remix-run/node"; import { - json, redirect, useLoaderData } from "@remix-run/react"; diff --git a/app/routes/admin/edit/beerstyle.$id.tsx b/app/routes/admin/edit/beerstyle.$id.tsx index b3a62c3..703e09a 100644 --- a/app/routes/admin/edit/beerstyle.$id.tsx +++ b/app/routes/admin/edit/beerstyle.$id.tsx @@ -1,7 +1,7 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json, redirect } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { Container, Row, Col, Button, Form, ListGroup } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Button, Container, Form, Row } from "react-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/edit/beerstyle.tsx b/app/routes/admin/edit/beerstyle.tsx index 24658a0..e9e9220 100644 --- a/app/routes/admin/edit/beerstyle.tsx +++ b/app/routes/admin/edit/beerstyle.tsx @@ -1,8 +1,6 @@ -import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { countBy } from "lodash"; -import { Container, Row, Col, Button, Form, ListGroup, Badge } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Badge, Button, Col, Container, ListGroup, Row } from "react-bootstrap"; import { LinkContainer } from "react-router-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/edit/container.$id.tsx b/app/routes/admin/edit/container.$id.tsx index 05eccf8..45eb1ca 100644 --- a/app/routes/admin/edit/container.$id.tsx +++ b/app/routes/admin/edit/container.$id.tsx @@ -1,10 +1,10 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json, redirect } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; -import { Container, Row, Button, Form, Col, ListGroup, InputGroup } from "react-bootstrap"; +import { Button, Container, Form, InputGroup, Row } from "react-bootstrap"; -import { enhance } from "~/utils/db.server"; import { ContainerType } from "@prisma/client"; +import { enhance } from "~/utils/db.server"; export const action = async ({ request, @@ -116,6 +116,7 @@ export default function EditContainerRoute() { + diff --git a/app/routes/admin/edit/container.tsx b/app/routes/admin/edit/container.tsx index 389da2e..977ae8d 100644 --- a/app/routes/admin/edit/container.tsx +++ b/app/routes/admin/edit/container.tsx @@ -1,8 +1,6 @@ -import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { countBy } from "lodash"; -import { Container, Row, Col, Button, Form, ListGroup, Badge } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Badge, Button, Col, Container, ListGroup, Row } from "react-bootstrap"; import { LinkContainer } from "react-router-bootstrap"; import { containerTypeToString } from "~/models/types"; import { volume } from "~/utils/conversions"; diff --git a/app/routes/admin/edit/country.$code.tsx b/app/routes/admin/edit/country.$code.tsx index 5177e97..70d20b4 100644 --- a/app/routes/admin/edit/country.$code.tsx +++ b/app/routes/admin/edit/country.$code.tsx @@ -1,7 +1,7 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json, redirect } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { Container, Row, Col, Button, Form, ListGroup } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Button, Container, Form, Row } from "react-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/edit/country.tsx b/app/routes/admin/edit/country.tsx index 8cda032..d8d0ece 100644 --- a/app/routes/admin/edit/country.tsx +++ b/app/routes/admin/edit/country.tsx @@ -1,8 +1,6 @@ -import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { countBy } from "lodash"; -import { Container, Row, Col, Button, Form, ListGroup, Badge } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Badge, Button, Col, Container, ListGroup, Row } from "react-bootstrap"; import { LinkContainer } from "react-router-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/edit/manufacturer.tsx b/app/routes/admin/edit/manufacturer.tsx index fe04f68..55dc385 100644 --- a/app/routes/admin/edit/manufacturer.tsx +++ b/app/routes/admin/edit/manufacturer.tsx @@ -1,8 +1,6 @@ -import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { countBy } from "lodash"; -import { Container, Row, Col, Button, Form, ListGroup, Badge } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Badge, Button, Col, Container, ListGroup, Row } from "react-bootstrap"; import { LinkContainer } from "react-router-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/edit/section.$id.tsx b/app/routes/admin/edit/section.$id.tsx index 3390399..9a20dac 100644 --- a/app/routes/admin/edit/section.$id.tsx +++ b/app/routes/admin/edit/section.$id.tsx @@ -1,7 +1,7 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json, redirect } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { Container, Row, Col, Button, Form, ListGroup } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Button, Container, Form, Row } from "react-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/edit/section.tsx b/app/routes/admin/edit/section.tsx index 0d60c0d..770b973 100644 --- a/app/routes/admin/edit/section.tsx +++ b/app/routes/admin/edit/section.tsx @@ -1,8 +1,6 @@ -import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { countBy } from "lodash"; -import { Container, Row, Col, Button, Form, ListGroup, Badge } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Badge, Button, Col, Container, ListGroup, Row } from "react-bootstrap"; import { LinkContainer } from "react-router-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/edit/winestyle.$id.tsx b/app/routes/admin/edit/winestyle.$id.tsx index f276d42..733d6cf 100644 --- a/app/routes/admin/edit/winestyle.$id.tsx +++ b/app/routes/admin/edit/winestyle.$id.tsx @@ -1,7 +1,7 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json, redirect } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { Container, Row, Col, Button, Form, ListGroup } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Button, Container, Form, Row } from "react-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/layout.tsx b/app/routes/admin/layout.tsx index 0066ea5..778c03d 100644 --- a/app/routes/admin/layout.tsx +++ b/app/routes/admin/layout.tsx @@ -1,4 +1,3 @@ -import { UserType } from "@prisma/client"; import { LoaderFunctionArgs, redirect } from "@remix-run/node"; import { Outlet, json, useLoaderData } from "@remix-run/react"; import { Container, Row } from "react-bootstrap"; diff --git a/app/routes/admin/manage/checkout.tsx b/app/routes/admin/manage/checkout.tsx index 80913fa..6ed646b 100644 --- a/app/routes/admin/manage/checkout.tsx +++ b/app/routes/admin/manage/checkout.tsx @@ -2,7 +2,6 @@ import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { Button, Form } from "react-bootstrap"; -import { containerTypeToString } from "~/models/types"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/new/beer.tsx b/app/routes/admin/new/beer.tsx index 6d6aa24..a2f365e 100644 --- a/app/routes/admin/new/beer.tsx +++ b/app/routes/admin/new/beer.tsx @@ -1,8 +1,8 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, NodeOnDiskFile, json, redirect, unstable_composeUploadHandlers, unstable_createFileUploadHandler, unstable_createMemoryUploadHandler, unstable_parseMultipartFormData } from "@remix-run/node"; +import { useLoaderData } from "@remix-run/react"; import { renameSync, rmSync } from "node:fs"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { Container, Row, Button, Form, Col, ListGroup, InputGroup } from "react-bootstrap"; +import { Button, Container, Form, InputGroup, Row } from "react-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/new/cocktail.tsx b/app/routes/admin/new/cocktail.tsx index eb8253b..1580b3d 100644 --- a/app/routes/admin/new/cocktail.tsx +++ b/app/routes/admin/new/cocktail.tsx @@ -1,8 +1,8 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, NodeOnDiskFile, json, redirect, unstable_composeUploadHandlers, unstable_createFileUploadHandler, unstable_createMemoryUploadHandler, unstable_parseMultipartFormData } from "@remix-run/node"; +import { useLoaderData } from "@remix-run/react"; import { renameSync, rmSync } from "node:fs"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { Container, Row, Button, Form, Col, ListGroup, InputGroup } from "react-bootstrap"; +import { Button, Container, Form, InputGroup, Row } from "react-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/new/container.tsx b/app/routes/admin/new/container.tsx index dc31f5a..35a059b 100644 --- a/app/routes/admin/new/container.tsx +++ b/app/routes/admin/new/container.tsx @@ -1,10 +1,10 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, json, redirect } from "@remix-run/node"; -import { isRouteErrorResponse, useLoaderData, useRouteError } from "@remix-run/react"; -import { Container, Row, Button, Form, Col, ListGroup, InputGroup } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Button, Container, Form, InputGroup, Row } from "react-bootstrap"; -import { enhance } from "~/utils/db.server"; import { ContainerType } from "@prisma/client"; +import { enhance } from "~/utils/db.server"; export const action = async ({ request, @@ -89,6 +89,7 @@ export default function NewContainerRoute() { + diff --git a/app/routes/admin/new/soda.tsx b/app/routes/admin/new/soda.tsx index 0c616dc..6dc2b1c 100644 --- a/app/routes/admin/new/soda.tsx +++ b/app/routes/admin/new/soda.tsx @@ -1,8 +1,8 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, NodeOnDiskFile, json, redirect, unstable_composeUploadHandlers, unstable_createFileUploadHandler, unstable_createMemoryUploadHandler, unstable_parseMultipartFormData } from "@remix-run/node"; +import { useLoaderData } from "@remix-run/react"; import { renameSync, rmSync } from "node:fs"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { Container, Row, Button, Form, Col, ListGroup, InputGroup } from "react-bootstrap"; +import { Button, Container, Form, InputGroup, Row } from "react-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/admin/new/wine.tsx b/app/routes/admin/new/wine.tsx index e9de82b..7b953b4 100644 --- a/app/routes/admin/new/wine.tsx +++ b/app/routes/admin/new/wine.tsx @@ -1,8 +1,8 @@ import type { ActionFunctionArgs } from "@remix-run/node"; import { LoaderFunctionArgs, NodeOnDiskFile, json, redirect, unstable_composeUploadHandlers, unstable_createFileUploadHandler, unstable_createMemoryUploadHandler, unstable_parseMultipartFormData } from "@remix-run/node"; +import { useLoaderData } from "@remix-run/react"; import { renameSync, rmSync } from "node:fs"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { Container, Row, Button, Form, Col, ListGroup, InputGroup } from "react-bootstrap"; +import { Button, Container, Form, InputGroup, Row } from "react-bootstrap"; import { enhance } from "~/utils/db.server"; diff --git a/app/routes/inventory/beer.$beerslug.tsx b/app/routes/inventory/beer.$beerslug.tsx index 335ecba..3d56dc4 100644 --- a/app/routes/inventory/beer.$beerslug.tsx +++ b/app/routes/inventory/beer.$beerslug.tsx @@ -11,7 +11,7 @@ import { import DrinkPage from "~/components/cards/drink.page"; -import { findIdFromSlug } from "~/models/drinks.server"; +import { findIdFromSlug, findRecommendations, getMostCommonSection } from "~/models/drinks.server"; import { enhance } from "~/utils/db.server"; export const loader = async ({ @@ -32,17 +32,19 @@ export const loader = async ({ }); } + const recommendations = await findRecommendations(await getMostCommonSection(beer.containers), 2, beer.id); + let user = session.get("user"); let isAdmin = user?.type == "Admin"; - return json({ beer , isAdmin: isAdmin}); + return json({ beer , recommendations, isAdmin: isAdmin}); }; export default function BeerRoute() { const data = useLoaderData(); return ( - + ); } diff --git a/app/routes/inventory/cocktail.$cocktailslug.tsx b/app/routes/inventory/cocktail.$cocktailslug.tsx index 135c0e1..7f8cf63 100644 --- a/app/routes/inventory/cocktail.$cocktailslug.tsx +++ b/app/routes/inventory/cocktail.$cocktailslug.tsx @@ -10,7 +10,7 @@ import { import DrinkPage from "~/components/cards/drink.page"; -import { findIdFromSlug } from "~/models/drinks.server"; +import { findIdFromSlug, findRecommendations, getMostCommonSection } from "~/models/drinks.server"; import { enhance } from "~/utils/db.server"; export const loader = async ({ @@ -31,17 +31,19 @@ params, }); } + const recommendations = await findRecommendations(await getMostCommonSection(cocktail.containers), 2, cocktail.id); + let user = session.get("user"); let isAdmin = user?.type == "Admin"; - return json({ cocktail , isAdmin: isAdmin}); + return json({ cocktail, recommendations, isAdmin: isAdmin}); }; export default function CocktailRoute() { const data = useLoaderData(); return ( - + ); } diff --git a/app/routes/inventory/drink.$id.tsx b/app/routes/inventory/drink.$id.tsx index d8f5518..769eef4 100644 --- a/app/routes/inventory/drink.$id.tsx +++ b/app/routes/inventory/drink.$id.tsx @@ -3,6 +3,7 @@ import type { LoaderFunctionArgs } from "@remix-run/node"; import { redirect } from "@remix-run/node"; +import { findIdFromSlug } from "~/models/drinks.server"; @@ -14,8 +15,10 @@ export const loader = async ({ }: LoaderFunctionArgs) => { const {dbe, session} = await enhance(request); - var id = Number(params.id); + var id = await findIdFromSlug(params.id) || 0; + var type : DrinkType = "Beer"; + var slug : string = params.id || ""; var drink; @@ -31,11 +34,12 @@ export const loader = async ({ drink = await dbe.drink.findUnique({ where: { id: id }, - select: {id: true, type: true} + select: {id: true, slug: true, type: true} }); if(drink){ type = drink.type; + slug = drink.slug; break; } @@ -52,5 +56,5 @@ export const loader = async ({ } } - return redirect("/inventory/" + type.toLowerCase() + "/" + id); + return redirect("/inventory/" + type.toLowerCase() + "/" + slug); }; \ No newline at end of file diff --git a/app/routes/inventory/manufacturer.$id.tsx b/app/routes/inventory/manufacturer.$id.tsx index b2da15d..4f1bbb9 100644 --- a/app/routes/inventory/manufacturer.$id.tsx +++ b/app/routes/inventory/manufacturer.$id.tsx @@ -1,19 +1,15 @@ -import type { +import type { LoaderFunctionArgs } from "@remix-run/node"; import { json } from "@remix-run/node"; -import { - useLoaderData, - useParams, - isRouteErrorResponse, - useRouteError } from "@remix-run/react"; +import { + useLoaderData +} from "@remix-run/react"; -import DrinkPage from "~/components/cards/drink.page"; -import { db } from "~/utils/db.server"; import { enhance } from "@zenstackhq/runtime"; -import { findIdFromSlug } from "~/models/drinks.server"; import { Col, Container, Image, Row } from "react-bootstrap"; +import { db } from "~/utils/db.server"; export const loader = async ({ params, diff --git a/app/routes/inventory/soda.$sodaslug.tsx b/app/routes/inventory/soda.$sodaslug.tsx index 3390236..a5d5bfe 100644 --- a/app/routes/inventory/soda.$sodaslug.tsx +++ b/app/routes/inventory/soda.$sodaslug.tsx @@ -10,7 +10,7 @@ import { import DrinkPage from "~/components/cards/drink.page"; -import { findIdFromSlug } from "~/models/drinks.server"; +import { findIdFromSlug, findRecommendations, getMostCommonSection } from "~/models/drinks.server"; import { enhance } from "~/utils/db.server"; export const loader = async ({ @@ -31,17 +31,19 @@ params, }); } + const recommendations = await findRecommendations(await getMostCommonSection(soda.containers), 2, soda.id); + let user = session.get("user"); let isAdmin = user?.type == "Admin"; - return json({ soda , isAdmin: isAdmin}); + return json({ soda , recommendations, isAdmin: isAdmin}); }; export default function SodaRoute() { const data = useLoaderData(); return ( - + ); } diff --git a/app/routes/inventory/stats/route.tsx b/app/routes/inventory/stats/route.tsx index 871c3e6..ed246fe 100644 --- a/app/routes/inventory/stats/route.tsx +++ b/app/routes/inventory/stats/route.tsx @@ -1,5 +1,5 @@ import { LoaderFunctionArgs, json } from "@remix-run/node"; -import { Link, useLoaderData } from "@remix-run/react"; +import { useLoaderData } from "@remix-run/react"; import { enhance } from "@zenstackhq/runtime"; import { Button, Col, Container, Row, Table } from "react-bootstrap"; import { LinkContainer } from "react-router-bootstrap"; diff --git a/app/routes/inventory/suggestions/route.tsx b/app/routes/inventory/suggestions/route.tsx new file mode 100644 index 0000000..79c3e25 --- /dev/null +++ b/app/routes/inventory/suggestions/route.tsx @@ -0,0 +1,116 @@ +import { ActionFunctionArgs, LoaderFunctionArgs, json } from "@remix-run/node"; +import { useLoaderData } from "@remix-run/react"; +import { Button, Col, Container, Form, Row, Table } from "react-bootstrap"; +import timeAgo from "~/utils/datetime"; + +import { enhance } from "~/utils/db.server"; + +export const action = async ({ + request +}: ActionFunctionArgs) => { + const { dbe } = await enhance(request); + + const form = await request.formData(); + + const content = String(form.get("content")); + var name : string | null = String(form.get("name")) || null; + if(name == "") name = null; + + if(content == "") return null; + + try{ + await dbe.suggestion.create({ data: { + name: name, + content: content + } + }); + } + catch(e){ + console.log(e); + } + + return null; +}; + +export const loader = async ({request} : LoaderFunctionArgs) => { + const { dbe } = await enhance(request); + + const suggestions = await dbe.suggestion.findMany({take: 15, orderBy: {createdAt: "desc"}}); + + return json({suggestions}); +}; + +export default function SuggestionsRoute() { + const loadData = useLoaderData(); + + return ( + + + +

Make a suggestion

+

Leave a suggestion about a drink, the website or anything really.

+
+ + + + Your name: + + + + + + + Suggestion*: + + + + + +
+ +
+ + {loadData.suggestions.length > 0 ? ( + +

Suggestions

+ + + + + + + + + + {loadData.suggestions.map((entry) => ( + + + + + + ))} + +
NameDateSuggestions
{entry.name ? (<>{entry.name}) : ( <>No name ) }{timeAgo(new Date(entry.createdAt))}{entry.content}
+ + ) : ( + +

Suggestions

+ No suggestions yet... + + )} +
+
+ ); +} + + diff --git a/app/routes/inventory/wine.$wineslug.tsx b/app/routes/inventory/wine.$wineslug.tsx index 4302006..939d626 100644 --- a/app/routes/inventory/wine.$wineslug.tsx +++ b/app/routes/inventory/wine.$wineslug.tsx @@ -10,7 +10,7 @@ import { import DrinkPage from "~/components/cards/drink.page"; -import { findIdFromSlug } from "~/models/drinks.server"; +import { findIdFromSlug, findRecommendations, getMostCommonSection } from "~/models/drinks.server"; import { enhance } from "~/utils/db.server"; export const loader = async ({ @@ -30,17 +30,20 @@ params, status: 404, }); } + + const recommendations = await findRecommendations(await getMostCommonSection(wine.containers), 2, wine.id); + let user = session.get("user"); let isAdmin = user?.type == "Admin"; - return json({ wine , isAdmin: isAdmin}); + return json({ wine , recommendations, isAdmin: isAdmin}); }; export default function WineRoute() { const data = useLoaderData(); return ( - + ); } diff --git a/app/routes/login.tsx b/app/routes/login.tsx index 54579e1..924ea8f 100644 --- a/app/routes/login.tsx +++ b/app/routes/login.tsx @@ -1,12 +1,12 @@ import type { - ActionFunctionArgs, - LoaderFunctionArgs, - } from "@remix-run/node"; // or cloudflare/deno - import { json, redirect } from "@remix-run/node"; // or cloudflare/deno - import { useActionData, useLoaderData } from "@remix-run/react"; -import { Button, Col, Container, Form, InputGroup, Row } from "react-bootstrap"; + ActionFunctionArgs, + LoaderFunctionArgs, +} from "@remix-run/node"; // or cloudflare/deno +import { json, redirect } from "@remix-run/node"; // or cloudflare/deno +import { useActionData } from "@remix-run/react"; +import { Button, Col, Container, Form, Row } from "react-bootstrap"; - import { getSession, commitSession } from "~/auth/session"; + import { commitSession, getSession } from "~/auth/session"; import { validateCredentials } from "~/auth/validate"; export async function loader({ diff --git a/app/routes/resource/checkouts.tsx b/app/routes/resource/checkouts.tsx index 56726a5..94f727a 100644 --- a/app/routes/resource/checkouts.tsx +++ b/app/routes/resource/checkouts.tsx @@ -1,4 +1,4 @@ -import { LoaderFunctionArgs, redirect, json } from "@remix-run/node"; +import { LoaderFunctionArgs, json } from "@remix-run/node"; import { enhance } from "~/utils/db.server"; export async function loader({ diff --git a/app/routes/scan/link.$barcode.tsx b/app/routes/scan/link.$barcode.tsx index 1df8ff4..e3e8637 100644 --- a/app/routes/scan/link.$barcode.tsx +++ b/app/routes/scan/link.$barcode.tsx @@ -1,12 +1,10 @@ import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; -import { useActionData, useLoaderData } from "@remix-run/react"; -import { Button, Col, Container, Form, Row, Table } from "react-bootstrap"; +import { useLoaderData } from "@remix-run/react"; +import { Button, Container, Form, Row } from "react-bootstrap"; import { LinkContainer } from "react-router-bootstrap"; -import { getSession } from "~/auth/session"; -import timeAgo from "~/utils/datetime"; -import { db, enhance } from "~/utils/db.server"; +import { enhance } from "~/utils/db.server"; export async function loader({ request, diff --git a/app/routes/scan/route.tsx b/app/routes/scan/route.tsx index d0c2e8d..156ac9a 100644 --- a/app/routes/scan/route.tsx +++ b/app/routes/scan/route.tsx @@ -2,10 +2,9 @@ import type { ActionFunctionArgs, LoaderFunctionArgs } from "@remix-run/node"; import { json, redirect } from "@remix-run/node"; import { useActionData, useLoaderData } from "@remix-run/react"; import { Col, Container, Form, Row, Table } from "react-bootstrap"; -import { getSession } from "~/auth/session"; import timeAgo from "~/utils/datetime"; -import { db, enhance } from "~/utils/db.server"; +import { enhance } from "~/utils/db.server"; export async function loader({ request, @@ -16,7 +15,7 @@ export async function loader({ return redirect("/"); } - const history = await dbe.history.findMany({select: {checkoutAt: true, inventoryAfter: true, container: {select: {drink: true}}}, take: 10, orderBy: {checkoutAt: "desc"}}); + const history = await dbe.history.findMany({select: {id: true, checkoutAt: true, inventoryAfter: true, container: {select: {drink: true}}}, take: 10, orderBy: {checkoutAt: "desc"}}); return json({history}); } @@ -93,7 +92,7 @@ export default function ScanRoute() { {lData.history.map((entry) => ( - + {entry.container.drink.name} {timeAgo(new Date(entry.checkoutAt))} {entry.inventoryAfter} diff --git a/app/utils/arrays.ts b/app/utils/arrays.ts new file mode 100644 index 0000000..c657e4d --- /dev/null +++ b/app/utils/arrays.ts @@ -0,0 +1,8 @@ +export function shuffleArray(array : any[]) { + for (var i = array.length - 1; i > 0; i--) { + var j = Math.floor(Math.random() * (i + 1)); + var temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } +} \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index fa8ab32..bafa540 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -32,6 +32,7 @@ enum ContainerType { PlasticBottle Can Carton + Keg } /// @@delegate(type) @@ -204,3 +205,11 @@ model Session { user User? @relation(fields: [user_id], references: [id]) data String } + +/// @@allow('all', true) +model Suggestion { + id Int @id() @default(autoincrement()) + createdAt DateTime @default(now()) + name String? + content String +} diff --git a/schema.zmodel b/schema.zmodel index 0b55147..c98212d 100644 --- a/schema.zmodel +++ b/schema.zmodel @@ -30,6 +30,7 @@ enum ContainerType { PlasticBottle Can Carton + Keg } model Drink { @@ -220,4 +221,13 @@ model Session { @@allow('all', auth().id == user.id) @@allow('all', auth().type == Admin) +} + +model Suggestion { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + name String? + content String + + @@allow('all', true) } \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index c380feb..eab62ce 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -28,7 +28,8 @@ export default defineConfig({ route("cocktail/:cocktailslug", "routes/inventory/cocktail.$cocktailslug.tsx"); route("manufacturer/:id", "routes/inventory/manufacturer.$id.tsx"); - route("stats", "routes/inventory/stats/route.tsx"); + route("stats", "routes/inventory/stats/route.tsx"); + route("suggestions", "routes/inventory/suggestions/route.tsx"); });