Graph colors, page titles and many more fixes
This commit is contained in:
@@ -110,19 +110,6 @@ const sliderIbu = () =>
|
||||
))}
|
||||
|
||||
</Form.Group>
|
||||
<Form.Group controlId="drink-modifiers" className='bg-body-secondary rounded p-3 mt-3'>
|
||||
<Form.Label className='fw-bold'>Drink</Form.Label>
|
||||
{ ["Sugar-free", "Gluten-free", "Organic"].map(key => (
|
||||
<Form.Check
|
||||
id={"drinkmod-" + key}
|
||||
type="checkbox"
|
||||
label={key}
|
||||
name={key.toLowerCase()}
|
||||
value={1}
|
||||
defaultChecked={arg.searchParams.has(key.toLowerCase()) ? true : false}
|
||||
/>
|
||||
))}
|
||||
</Form.Group>
|
||||
<Form.Group controlId="drink-abv" className='bg-body-secondary rounded p-3 mt-3'>
|
||||
<Form.Label className='fw-bold'>ABV</Form.Label>
|
||||
{sliderAbv()}
|
||||
@@ -214,6 +201,19 @@ const sliderIbu = () =>
|
||||
/>
|
||||
</Form.Group>
|
||||
) : ""}
|
||||
<Form.Group controlId="drink-modifiers" className='bg-body-secondary rounded p-3 mt-3'>
|
||||
<Form.Label className='fw-bold'>Drink</Form.Label>
|
||||
{ ["Sugar-free", "Gluten-free", "Organic"].map(key => (
|
||||
<Form.Check
|
||||
id={"drinkmod-" + key}
|
||||
type="checkbox"
|
||||
label={key}
|
||||
name={key.toLowerCase()}
|
||||
value={1}
|
||||
defaultChecked={arg.searchParams.has(key.toLowerCase()) ? true : false}
|
||||
/>
|
||||
))}
|
||||
</Form.Group>
|
||||
<Form.Group controlId="inventory" className='bg-body-secondary rounded p-3 mt-3'>
|
||||
<Form.Label className='fw-bold'>No Inventory</Form.Label>
|
||||
<Form.Check
|
||||
@@ -226,6 +226,11 @@ const sliderIbu = () =>
|
||||
</Form.Group>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col className='text-center p-3'>
|
||||
<span className='fs-6 text-muted text-center'>Results are updated live</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { enhance } from "@zenstackhq/runtime";
|
||||
import { random_rgba } from "~/utils/color";
|
||||
import { drinkTypeToColor, random_rgba } from "~/utils/color";
|
||||
import timeAgo from "~/utils/datetime";
|
||||
import { db } from "~/utils/db.server";
|
||||
import { randomRange } from "~/utils/random";
|
||||
@@ -25,6 +25,7 @@ export async function generateMonthChartData(){
|
||||
|
||||
// History of specific drink
|
||||
const containersWithHistory = await dbe.container.findMany({
|
||||
orderBy: [{drink: {type: "asc"}}, {checkouts: {_count: "desc"}}],
|
||||
include: {drink: true, checkouts: {orderBy: {checkoutAt: "asc"}, where: {checkoutAt: {gte: dates[0]}}}}
|
||||
})
|
||||
|
||||
@@ -86,14 +87,14 @@ export async function generateMonthChartData(){
|
||||
inventoryAfter[i] = totalInventory;
|
||||
}
|
||||
|
||||
let [color1] = random_rgba(1);
|
||||
let color = drinkTypeToColor(container.drink.type);
|
||||
|
||||
datasets.push({
|
||||
type: 'bar',
|
||||
label: 'Checkouts ' + container.drink.name,
|
||||
data: checkouts,
|
||||
borderColor: color1,
|
||||
backgroundColor: color1,
|
||||
borderColor: color,
|
||||
backgroundColor: color,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -126,6 +127,7 @@ export async function generateMonthChartData(){
|
||||
|
||||
// History of specific drink
|
||||
const containersWithHistory = await dbe.container.findMany({
|
||||
orderBy: [{drink: {type: "asc"}}, {checkouts: {_count: "desc"}}],
|
||||
include: {drink: true, checkouts: {orderBy: {checkoutAt: "asc"}, where: {checkoutAt: {gte: hours[0]}}}}
|
||||
})
|
||||
|
||||
@@ -187,14 +189,14 @@ export async function generateMonthChartData(){
|
||||
inventoryAfter[i] = totalInventory;
|
||||
}
|
||||
|
||||
let [color1] = random_rgba(1);
|
||||
let color = drinkTypeToColor(container.drink.type);
|
||||
|
||||
datasets.push({
|
||||
type: 'bar',
|
||||
label: 'Checkouts ' + container.drink.name,
|
||||
data: checkouts,
|
||||
borderColor: color1,
|
||||
backgroundColor: color1,
|
||||
borderColor: color,
|
||||
backgroundColor: color,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { DrinkType } from "@prisma/client";
|
||||
import { enhance } from "@zenstackhq/runtime";
|
||||
import { hexToRGB, random_rgba } from "~/utils/color";
|
||||
import timeAgo from "~/utils/datetime";
|
||||
import { sortArrays } from "~/utils/arrays";
|
||||
import { drinkTypeToColor, hexToRGB } from "~/utils/color";
|
||||
import { db } from "~/utils/db.server";
|
||||
import { randomRange } from "~/utils/random";
|
||||
|
||||
export async function generateTypeInventoryChartData(){
|
||||
const dbe = enhance(db);
|
||||
@@ -19,7 +18,7 @@ export async function generateTypeInventoryChartData(){
|
||||
let typeT = DrinkType[type];
|
||||
|
||||
labels.push(type);
|
||||
colors.push(random_rgba(1)[0]);
|
||||
colors.push(drinkTypeToColor(typeT));
|
||||
const aggregate = await dbe.container.aggregate({_sum: {inventory: true}, where: {drink: {type: typeT}}});
|
||||
numset.push(aggregate._sum.inventory ?? 0);
|
||||
|
||||
@@ -56,7 +55,7 @@ export async function generateTypeInventoryChartData(){
|
||||
let colors : string[] = [];
|
||||
let numset : number[] = [];
|
||||
|
||||
const beerstyle = await dbe.beerStyle.findMany({});
|
||||
const beerstyle = await dbe.beerStyle.findMany({orderBy: {beers: {_count: "desc"}}});
|
||||
|
||||
for(let style of beerstyle){
|
||||
labels.push(style.name);
|
||||
@@ -67,13 +66,15 @@ export async function generateTypeInventoryChartData(){
|
||||
numset.push(reduced);
|
||||
}
|
||||
|
||||
let [sortedNumset, sortedColors, sortedLabels] = sortArrays([numset, colors, labels]);
|
||||
|
||||
const data = {
|
||||
labels,
|
||||
labels: sortedLabels,
|
||||
datasets: [{
|
||||
type: 'doughnut',
|
||||
label: 'Inventory',
|
||||
data: numset,
|
||||
backgroundColor: colors,
|
||||
data: sortedNumset,
|
||||
backgroundColor: sortedColors,
|
||||
}]
|
||||
};
|
||||
|
||||
@@ -93,7 +94,7 @@ export async function generateTypeInventoryChartData(){
|
||||
let typeT = DrinkType[type];
|
||||
|
||||
labels.push(type);
|
||||
colors.push(random_rgba(1)[0]);
|
||||
colors.push(drinkTypeToColor(typeT));
|
||||
const aggregate = await dbe.history.aggregate({_count: {_all: true}, where: {container: {drink: {type: typeT}}}});
|
||||
numset.push(aggregate._count._all ?? 0);
|
||||
|
||||
@@ -130,7 +131,7 @@ export async function generateTypeInventoryChartData(){
|
||||
let colors : string[] = [];
|
||||
let numset : number[] = [];
|
||||
|
||||
const beerstyle = await dbe.beerStyle.findMany({});
|
||||
const beerstyle = await dbe.beerStyle.findMany({orderBy: {beers: {_count: "desc"}}});
|
||||
|
||||
for(let style of beerstyle){
|
||||
labels.push(style.name);
|
||||
@@ -141,13 +142,15 @@ export async function generateTypeInventoryChartData(){
|
||||
numset.push(reduced);
|
||||
}
|
||||
|
||||
let [sortedNumset, sortedColors, sortedLabels] = sortArrays([numset, colors, labels]);
|
||||
|
||||
const data = {
|
||||
labels,
|
||||
labels: sortedLabels,
|
||||
datasets: [{
|
||||
type: 'doughnut',
|
||||
label: 'Checked out',
|
||||
data: numset,
|
||||
backgroundColor: colors,
|
||||
data: sortedNumset,
|
||||
backgroundColor: sortedColors,
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
import type { LinksFunction } from "@remix-run/node";
|
||||
import {
|
||||
Links,
|
||||
Meta,
|
||||
Outlet,
|
||||
Scripts,
|
||||
ScrollRestoration,
|
||||
@@ -29,7 +30,7 @@ function Document({
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1"
|
||||
/>
|
||||
<title>{title}</title>
|
||||
<Meta />
|
||||
<Links />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -36,6 +36,11 @@ export default function EditContainerRoute() {
|
||||
<Badge bg="secondary" className="ms-1">{timeAgo(new Date(checkout.checkoutAt))} - {checkout.checkoutAt.slice(0,-5)}</Badge>
|
||||
<Badge bg="secondary" className="ms-1">{checkout.inventoryAfter} left</Badge>
|
||||
<div className="float-end">
|
||||
<LinkContainer to={"/admin/remove/checkout/" + checkout.id}>
|
||||
<Button variant="danger">
|
||||
Remove
|
||||
</Button>
|
||||
</LinkContainer>
|
||||
<LinkContainer to={"" + checkout.id}>
|
||||
<Button variant="primary" className="mx-3">
|
||||
Edit
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { LoaderFunctionArgs, redirect } from "@remix-run/node";
|
||||
|
||||
import { enhance } from "~/utils/db.server";
|
||||
|
||||
export const loader = async ({
|
||||
request,
|
||||
params
|
||||
} : LoaderFunctionArgs) => {
|
||||
const { dbe } = await enhance(request);
|
||||
|
||||
const id = Number(params.id);
|
||||
|
||||
await dbe.history.delete({where: {id: id}});
|
||||
return redirect("/admin/edit/checkout");
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LoaderFunctionArgs, redirect } from "@remix-run/node";
|
||||
import { LoaderFunctionArgs, MetaFunction, redirect } from "@remix-run/node";
|
||||
import { Outlet, json, useLoaderData } from "@remix-run/react";
|
||||
import { Container, Row } from "react-bootstrap";
|
||||
import { getSession } from "~/auth/session";
|
||||
@@ -30,6 +30,10 @@ export async function loader({
|
||||
return json({data});
|
||||
}
|
||||
|
||||
export const meta: MetaFunction = ({}) => {
|
||||
return [{ title: "Admin | K-FRIDGE" }];
|
||||
};
|
||||
|
||||
export default function InventoryLayout() {
|
||||
let data = useLoaderData<typeof loader>();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type {
|
||||
LoaderFunctionArgs
|
||||
LoaderFunctionArgs,
|
||||
MetaFunction
|
||||
} from "@remix-run/node";
|
||||
import { json } from "@remix-run/node";
|
||||
import {
|
||||
@@ -51,6 +52,12 @@ export default function BeerRoute() {
|
||||
);
|
||||
}
|
||||
|
||||
export const meta: MetaFunction<typeof loader> = ({
|
||||
data,
|
||||
}) => {
|
||||
return [{ title: data?.beer.name + " | K-FRIDGE" }];
|
||||
};
|
||||
|
||||
export function ErrorBoundary() {
|
||||
const { beerid } = useParams();
|
||||
const error = useRouteError();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type {
|
||||
LoaderFunctionArgs
|
||||
LoaderFunctionArgs,
|
||||
MetaFunction
|
||||
} from "@remix-run/node";
|
||||
import { json } from "@remix-run/node";
|
||||
import {
|
||||
@@ -50,6 +51,12 @@ return (
|
||||
);
|
||||
}
|
||||
|
||||
export const meta: MetaFunction<typeof loader> = ({
|
||||
data,
|
||||
}) => {
|
||||
return [{ title: data?.cocktail.name + " | K-FRIDGE" }];
|
||||
};
|
||||
|
||||
export function ErrorBoundary() {
|
||||
const { cocktailid } = useParams();
|
||||
const error = useRouteError();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { LoaderFunctionArgs } from "@remix-run/node";
|
||||
import { LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
|
||||
import { Outlet, json, useFetcher, useLoaderData, useRevalidator } from "@remix-run/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { getSession } from "~/auth/session";
|
||||
@@ -23,6 +23,9 @@ export async function loader({
|
||||
}
|
||||
|
||||
|
||||
export const meta: MetaFunction = ({}) => {
|
||||
return [{ title: "Inventory | K-FRIDGE" }];
|
||||
};
|
||||
|
||||
export default function InventoryLayout() {
|
||||
let data = useLoaderData<typeof loader>();
|
||||
|
||||
@@ -50,7 +50,7 @@ export default function BeersRoute() {
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Row className="mt-3">
|
||||
<Row className="pt-1 sticky-top bg-white" style={{boxShadow: "0px 4px 4px -5px rgba(0,0,0,.5)"}}>
|
||||
<Col key="filtering" className="mb-3">
|
||||
<div>
|
||||
<Button variant="primary" onClick={handleShow}>Filters</Button>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type {
|
||||
LoaderFunctionArgs
|
||||
LoaderFunctionArgs,
|
||||
MetaFunction
|
||||
} from "@remix-run/node";
|
||||
import { json } from "@remix-run/node";
|
||||
import {
|
||||
@@ -50,6 +51,12 @@ export default function SodaRoute() {
|
||||
);
|
||||
}
|
||||
|
||||
export const meta: MetaFunction<typeof loader> = ({
|
||||
data,
|
||||
}) => {
|
||||
return [{ title: data?.soda.name + " | K-FRIDGE" }];
|
||||
};
|
||||
|
||||
export function ErrorBoundary() {
|
||||
const { sodaid } = useParams();
|
||||
const error = useRouteError();
|
||||
|
||||
@@ -14,6 +14,8 @@ import 'chart.js/auto';
|
||||
|
||||
import { db } from "~/utils/db.server";
|
||||
import { generateBeerHistoryChartData, generateBeerInventoryChartData, generateTypeHistoryChartData, generateTypeInventoryChartData } from "~/models/type.chart.server";
|
||||
import { drinkTypeToColor } from "~/utils/color";
|
||||
import { DrinkType } from "@prisma/client";
|
||||
|
||||
function statsForContainers(containers : ContainerWithDrink[]){
|
||||
var drinksInventory = 0;
|
||||
@@ -119,6 +121,10 @@ export const loader = async ({request} : LoaderFunctionArgs) => {
|
||||
return json({total, chartDataTotal, chartDataBeerTotal, statsLast24H, chartData24H, statsLastMonth, chartDataMonth, statsTotal, chartDataHistoryTotal, chartDataBeerHistoryTotal, history});
|
||||
};
|
||||
|
||||
export const meta: MetaFunction = ({}) => {
|
||||
return [{ title: "Stats | K-FRIDGE" }];
|
||||
};
|
||||
|
||||
export default function StatsRoute() {
|
||||
const loadData = useLoaderData<typeof loader>();
|
||||
|
||||
@@ -208,19 +214,19 @@ export default function StatsRoute() {
|
||||
<td>{loadData.total.drinksInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Beers</td>
|
||||
<td className="ps-4"># Beers <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Beer)}}> </Badge></td>
|
||||
<td>{loadData.total.beersInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Wines</td>
|
||||
<td className="ps-4"># Wines <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Wine)}}> </Badge></td>
|
||||
<td>{loadData.total.wineInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Sodas</td>
|
||||
<td className="ps-4"># Sodas <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Soda)}}> </Badge></td>
|
||||
<td>{loadData.total.sodaInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Cocktails</td>
|
||||
<td className="ps-4"># Cocktails <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Cocktail)}}> </Badge></td>
|
||||
<td>{loadData.total.cocktailInventory}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -273,19 +279,19 @@ export default function StatsRoute() {
|
||||
<td>{loadData.statsTotal.drinksInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Beers</td>
|
||||
<td className="ps-4"># Beers <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Beer)}}> </Badge></td>
|
||||
<td>{loadData.statsTotal.beersInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Wines</td>
|
||||
<td className="ps-4"># Wines <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Wine)}}> </Badge></td>
|
||||
<td>{loadData.statsTotal.wineInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Sodas</td>
|
||||
<td className="ps-4"># Sodas <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Soda)}}> </Badge></td>
|
||||
<td>{loadData.statsTotal.sodaInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Cocktails</td>
|
||||
<td className="ps-4"># Cocktails <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Cocktail)}}> </Badge></td>
|
||||
<td>{loadData.statsTotal.cocktailInventory}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -338,19 +344,19 @@ export default function StatsRoute() {
|
||||
<td>{loadData.statsLastMonth.drinksInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Beers</td>
|
||||
<td className="ps-4"># Beers <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Beer)}}> </Badge></td>
|
||||
<td>{loadData.statsLastMonth.beersInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Wines</td>
|
||||
<td className="ps-4"># Wines <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Wine)}}> </Badge></td>
|
||||
<td>{loadData.statsLastMonth.wineInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Sodas</td>
|
||||
<td className="ps-4"># Sodas <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Soda)}}> </Badge></td>
|
||||
<td>{loadData.statsLastMonth.sodaInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Cocktails</td>
|
||||
<td className="ps-4"># Cocktails <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Cocktail)}}> </Badge></td>
|
||||
<td>{loadData.statsLastMonth.cocktailInventory}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -394,19 +400,19 @@ export default function StatsRoute() {
|
||||
<td>{loadData.statsLast24H.drinksInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Beers</td>
|
||||
<td className="ps-4"># Beers <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Beer)}}> </Badge></td>
|
||||
<td>{loadData.statsLast24H.beersInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Wines</td>
|
||||
<td className="ps-4"># Wines <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Wine)}}> </Badge></td>
|
||||
<td>{loadData.statsLast24H.wineInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Sodas</td>
|
||||
<td className="ps-4"># Sodas <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Soda)}}> </Badge></td>
|
||||
<td>{loadData.statsLast24H.sodaInventory}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="ps-4"># Cocktails</td>
|
||||
<td className="ps-4"># Cocktails <Badge bg="" style={{backgroundColor: drinkTypeToColor(DrinkType.Cocktail)}}> </Badge></td>
|
||||
<td>{loadData.statsLast24H.cocktailInventory}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ActionFunctionArgs, EntryContext, LoaderFunctionArgs, json } from "@remix-run/node";
|
||||
import { ActionFunctionArgs, EntryContext, LoaderFunctionArgs, MetaFunction, json } from "@remix-run/node";
|
||||
import { useLoaderData } from "@remix-run/react";
|
||||
import { Button, Col, Container, Form, Row, Table } from "react-bootstrap";
|
||||
import { LinkContainer } from "react-router-bootstrap";
|
||||
@@ -44,6 +44,10 @@ export const loader = async ({request} : LoaderFunctionArgs) => {
|
||||
return json({suggestions, isAdmin});
|
||||
};
|
||||
|
||||
export const meta: MetaFunction = ({}) => {
|
||||
return [{ title: "Suggestions | K-FRIDGE" }];
|
||||
};
|
||||
|
||||
export default function SuggestionsRoute() {
|
||||
const loadData = useLoaderData<typeof loader>();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type {
|
||||
LoaderFunctionArgs
|
||||
LoaderFunctionArgs,
|
||||
MetaFunction
|
||||
} from "@remix-run/node";
|
||||
import { json } from "@remix-run/node";
|
||||
import {
|
||||
@@ -50,6 +51,12 @@ export default function WineRoute() {
|
||||
);
|
||||
}
|
||||
|
||||
export const meta: MetaFunction<typeof loader> = ({
|
||||
data,
|
||||
}) => {
|
||||
return [{ title: data?.wine.name + " | K-FRIDGE" }];
|
||||
};
|
||||
|
||||
export function ErrorBoundary() {
|
||||
const { wineid } = useParams();
|
||||
const error = useRouteError();
|
||||
|
||||
@@ -5,4 +5,20 @@ export function shuffleArray(array : any[]) {
|
||||
array[i] = array[j];
|
||||
array[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts all arrays together with the first. Pass either a list of arrays, or a map. Any key is accepted.
|
||||
* Array|Object arrays [sortableArray, ...otherArrays]; {sortableArray: [], secondaryArray: [], ...}
|
||||
* Function comparator(?,?) -> int optional compareFunction, compatible with Array.sort(compareFunction)
|
||||
*/
|
||||
export function sortArrays(arrays : any[][], comparator = (a:any, b:any) => (a < b) ? 1 : (a > b) ? -1 : 0) {
|
||||
let arrayKeys = Object.keys(arrays);
|
||||
let sortableArray : (typeof arrays[0][0]) = Object.values(arrays)[0];
|
||||
let indexes = Object.keys(sortableArray);
|
||||
let sortedIndexes = indexes.sort((a, b) => comparator(sortableArray[a], sortableArray[b]));
|
||||
|
||||
let sortByIndexes = (array : any[], sortedIndexes : number[]) => sortedIndexes.map(sortedIndex => array[sortedIndex]);
|
||||
|
||||
return arrayKeys.map(arrayIndex => sortByIndexes(arrays[arrayIndex], sortedIndexes));
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { DrinkType } from "@prisma/client";
|
||||
|
||||
export function random_rgba(numShades : number) {
|
||||
let o = Math.round, r = Math.random, s = 155, m = 100;
|
||||
|
||||
@@ -24,4 +26,18 @@ export function hexToRGB(hex : string, alpha : number) {
|
||||
} else {
|
||||
return "rgb(" + r + ", " + g + ", " + b + ")";
|
||||
}
|
||||
}
|
||||
|
||||
export function drinkTypeToColor(type: DrinkType){
|
||||
switch(type){
|
||||
default:
|
||||
case DrinkType.Beer:
|
||||
return 'rgba(255, 164, 18, 1)';
|
||||
case DrinkType.Cocktail:
|
||||
return 'rgba(83, 185, 219, 1)';
|
||||
case DrinkType.Soda:
|
||||
return 'rgba(188, 71, 214, 1)';
|
||||
case DrinkType.Wine:
|
||||
return 'rgba(178, 21, 58, 1)'
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,7 @@ export default defineConfig({
|
||||
|
||||
route("edit/checkout", "routes/admin/edit/checkout.tsx");
|
||||
route("edit/checkout/:id", "routes/admin/edit/checkout.$id.tsx");
|
||||
route("remove/checkout/:id", "routes/admin/edit/remove/checkout.$id.tsx");
|
||||
route("remove/checkouts/:containerid", "routes/admin/edit/remove/checkouts.$containerid.tsx");
|
||||
|
||||
route("remove/suggestion/:id", "routes/admin/edit/remove/suggestion.$id.tsx");
|
||||
|
||||
Reference in New Issue
Block a user