Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caretaker Flow #8

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,15 @@ body {
text-wrap: balance;
}
} */

@layer utilities {
/* Hide scrollbar for Chrome, Safari and Opera */
.no-scrollbar::-webkit-scrollbar {
display: none;
}
/* Hide scrollbar for IE, Edge and Firefox */
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
}
103 changes: 103 additions & 0 deletions app/mess/AddFoodItems.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Typography } from "@/components/components";
import { CreateMenuItem, MenuItem } from "@/types/meal";
import { Mess, MessPopulated } from "@/types/mess";
import { Button, Input, NumberInput, TextInput } from "@mantine/core";
import { IconCircleCheck } from "@tabler/icons-react";
import React, { useState } from "react";

function AddMenuItem({
messId,
close,
editMenu,
}: {
messId: string;
close: () => void;
editMenu?: MenuItem;
}) {
const [menuItem, setMenuItem] = useState<CreateMenuItem>({
cost: editMenu?.cost || NaN,
label: editMenu?.label || "",
mess: messId,
description: editMenu?.description || "",
});
const [submitted, setSubmitted] = useState<boolean>(false);

const handleSubmit = () => {
setSubmitted(true);
};

return (
<div className="w-full">
{!submitted && (
<div>
<div className="my-2">
<Input.Label className="font-bold" required>
Food item name
</Input.Label>
<Input.Description className="mt-[-1px] font-light">
eg Paneer Butter masala etc..
</Input.Description>
<TextInput
value={menuItem.label}
onChange={(e) =>
setMenuItem({ ...menuItem, label: e.target.value })
}
/>
</div>
<div className="my-2">
<Input.Label className="font-bold" required>
Food item cost
</Input.Label>
<Input.Description className="mt-[-1px] font-light">
This cost will only be applicable if the item is taken as an extra
item. It will have no effect in the total meal price
</Input.Description>
<NumberInput
value={menuItem.cost}
min={0}
onChange={(value) =>
setMenuItem({ ...menuItem, cost: Number(value) })
}
leftSection={"₹"}
/>
</div>
<div className="my-2">
<Input.Label className="font-bold">Description</Input.Label>
<Input.Description className="mt-[-1px] font-light">
eg. Ingredients, way of making etc
</Input.Description>
<TextInput
value={menuItem.description}
onChange={(e) =>
setMenuItem({ ...menuItem, description: e.target.value })
}
/>
</div>
<div className="my-1">
<Button
fullWidth
size="xs"
disabled={!(!Number.isNaN(menuItem.cost) && menuItem.label != "")}
onClick={handleSubmit}
>
{editMenu ? "UPDATE" : "SUBMIT"}
</Button>
</div>
</div>
)}
{submitted && (
<div className="my-2 flex w-full flex-col items-center justify-center gap-3">
<IconCircleCheck size={50} />
<Typography variant="h6">Food Item Added !</Typography>
<div className="my-1 w-full">
<Button fullWidth size="xs" onClick={close}>
OK
</Button>
</div>
</div>
)}
</div>
);
}

export default AddMenuItem;
96 changes: 67 additions & 29 deletions app/mess/Menu.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
"use client";
import { IconCalendar, IconChevronRight, IconPlus } from "@tabler/icons-react";
import React, { useEffect, useState } from "react";
import { Spinner, Typography } from "@/components/components";
import { DatePicker } from "@mantine/dates";
import { dummyMealPopulated } from "@/temp/menu";
import { MealPopulated, MenuItem } from "@/types/meal";
import {
ActionIcon,
ComboboxData,
Divider,
Input,
Modal,
NavLink,
ScrollArea,
Select,
Tooltip,
} from "@mantine/core";
import { DatePicker } from "@mantine/dates";
import { useDisclosure } from "@mantine/hooks";
import {
IconCalendar,
IconChevronRight,
IconClock,
IconFridge,
IconInfoCircle,
IconPlus,
IconToolsKitchen2,
} from "@tabler/icons-react";
import { useQuery } from "@tanstack/react-query";
import { Day, MealPopulated } from "@/types/meal";
import { dummyMealPopulated } from "@/temp/menu";
import { useEffect, useState } from "react";
import MenuTemplate from "./MenuTemplate";
import { MessPopulated } from "@/types/mess";
import AddMenuItem from "./AddFoodItems";
import MenuItemViewer from "./MenuItemViewer";

export interface MealMap {
[key: string]: MealPopulated;
}

function MenuDisplay({ date }: { date: Date }) {
function MenuDisplay({ date, mess }: { date: Date; mess: MessPopulated }) {
const mealFetchCall = useQuery({
queryKey: [`menu_display_${date}`],
queryFn: () => {
Expand All @@ -28,6 +44,8 @@ function MenuDisplay({ date }: { date: Date }) {

const [selectedMeal, setSelectedMeal] = useState<MealPopulated>();
const [mealTypeOptions, setMealTypeOptions] = useState<ComboboxData>([]);
const [modifyMenuModalState, modifyMenuModal] = useDisclosure();
const [addMenuItemsModalState, addMenuItemsModal] = useDisclosure();

const mealPopulatedListToMealTypeMapper = (
mealPopulatedList: Array<MealPopulated>,
Expand Down Expand Up @@ -68,6 +86,22 @@ function MenuDisplay({ date }: { date: Date }) {

return (
<div>
<Modal
opened={modifyMenuModalState}
onClose={modifyMenuModal.close}
centered
title="Modify Meal Plan"
>
<MenuTemplate messId={mess._id} close={modifyMenuModal.close} />
</Modal>
<Modal
opened={addMenuItemsModalState}
onClose={addMenuItemsModal.close}
centered
title="Add Food Items"
>
<AddMenuItem messId={mess._id} close={addMenuItemsModal.close} />
</Modal>
<div className="my-2">
<Select
data={mealTypeOptions}
Expand All @@ -79,31 +113,35 @@ function MenuDisplay({ date }: { date: Date }) {
}
/>
</div>
<div>
<div className=""></div>
</div>
<div className="mt-5 flex items-center justify-between">
<div>
<Typography variant="h6">Food Menu</Typography>
{!mealFetchCall.isLoading && (
<p className="text-xs font-light">
Total{" "}
<b className="text-green-500">
{Object.keys(mealFetchCall.data || {}).length}
</b>{" "}
items
</p>
)}
</div>
<div className="flex gap-2">
<IconPlus className="cursor-pointer" />
<div className="flex justify-between">
<div className="flex items-center gap-1">
<IconClock size={15} />
<p>
{selectedMeal?.type.startTime} - {selectedMeal?.type.endTime}
</p>
</div>
<p>₹ {selectedMeal?.type.cost}</p>
</div>
{mealFetchCall.isLoading && <Spinner className="m-auto my-5" />}
{!mealFetchCall.isLoading && (
<div className="my-5">
{mealFetchCall.data?.length ? (
<div className=""></div>
{selectedMeal?.menu.length ? (
<div className="">
<MenuItemViewer mess={mess} menu={selectedMeal.menu} />
<Divider className="my-2" />
<NavLink
leftSection={<IconToolsKitchen2 size={20} />}
rightSection={<IconChevronRight />}
label="Add Food Items"
onClick={() => addMenuItemsModal.open()}
/>
<NavLink
leftSection={<IconFridge size={20} />}
rightSection={<IconChevronRight />}
label="Modify Meal Plan"
onClick={() => modifyMenuModal.open()}
/>
</div>
) : (
<div className="m-auto text-center text-sm">Nothing to display</div>
)}
Expand All @@ -113,7 +151,7 @@ function MenuDisplay({ date }: { date: Date }) {
);
}

function Menu() {
function Menu({ mess }: { mess: MessPopulated }) {
const [chosenDate, setChosenDate] = useState<Date>(new Date());
const [showDatePicker, setShowDatePicker] = useState<boolean>(false);
return (
Expand Down Expand Up @@ -145,7 +183,7 @@ function Menu() {
/>

<div>
<MenuDisplay date={chosenDate} />
<MenuDisplay date={chosenDate} mess={mess} />
</div>
</div>
)}
Expand Down
82 changes: 82 additions & 0 deletions app/mess/MenuItemViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"use client";
import { MenuItem } from "@/types/meal";
import React, { useState } from "react";
import { Typography } from "@/components/components";
import { Tooltip, NavLink, Modal } from "@mantine/core";
import { IconInfoCircle } from "@tabler/icons-react";
import { useDisclosure } from "@mantine/hooks";
import AddMenuItem from "./AddFoodItems";
import { MessPopulated } from "@/types/mess";

function MenuItemViewer({
mess,
menu,
edit,
}: {
mess?: MessPopulated;
menu: MenuItem[];
edit?: boolean;
}) {
const [editMenuItemModalState, editMenuItemModalAction] = useDisclosure();
const [selectedEditMenuItem, setSelectedEditMenuItem] = useState<MenuItem>();

return (
<div>
<Modal
onClose={editMenuItemModalAction.close}
opened={editMenuItemModalState}
title="Edit Menu Item"
>
<AddMenuItem
close={editMenuItemModalAction.close}
messId={mess?._id || ""}
editMenu={selectedEditMenuItem}
/>
</Modal>
<div className="my-2 flex items-center justify-between">
<Typography variant="h6">Item Name</Typography>
<div className="flex items-center gap-1">
<Tooltip
className="cursor-pointer"
label="The cost here only is effective if it is taken as an extra item"
variant="outlined"
>
<IconInfoCircle size={15} />
</Tooltip>
<Typography variant="h6">Extra Cost</Typography>
</div>
</div>
<div className="no-scrollbar max-h-[200px] overflow-y-scroll">
{menu?.map((menuItem: MenuItem) => (
<div
key={`Menu_Item_${menuItem._id}`}
className="my-3 flex items-center justify-between"
>
<div>
<Typography
variant="h6"
className={`text-sm font-medium ${edit && "cursor-pointer underline underline-offset-4"}`}
onClick={() => {
setSelectedEditMenuItem(menuItem);
editMenuItemModalAction.open();
}}
>
{menuItem.label}
</Typography>
{menuItem.description && (
<p className="mt-[-2px] text-xs font-light">
{menuItem.description}
</p>
)}
</div>
<Typography variant="h6" className="text-sm font-medium">
₹ {menuItem.cost}
</Typography>
</div>
))}
</div>
</div>
);
}

export default MenuItemViewer;
29 changes: 29 additions & 0 deletions app/mess/MenuItems.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Spinner } from "@/components/components";
import { dummyFoodItems } from "@/temp/menu";
import { MessPopulated } from "@/types/mess";
import { useQuery } from "@tanstack/react-query";
import React, { use } from "react";
import MenuItemViewer from "./MenuItemViewer";

function MenuItems({ mess }: { mess: MessPopulated }) {
const menuItemsFetchCall = useQuery({
queryKey: [`menu_items_${mess._id}`],
queryFn: () => {
return dummyFoodItems;
},
});
return (
<div className="my-4">
{menuItemsFetchCall.isLoading && (
<div className="my-5 flex items-center justify-center">
<Spinner />
</div>
)}
{!menuItemsFetchCall.isLoading && (
<MenuItemViewer mess={mess} menu={menuItemsFetchCall.data ?? []} edit />
)}
</div>
);
}

export default MenuItems;
Loading