All files / components/DiningCommons DiningCommonsTable.jsx

100% Statements 23/23
100% Branches 21/21
100% Functions 11/11
100% Lines 22/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97              2x 45x 7x 45x 45x 45x       27x     47x 47x   47x   12x         9x             46x         42x 2x 6x               8x 8x                     27x                                 47x         47x         47x            
import React from "react";
import OurTable from "main/components/OurTable";
import { Link } from "react-router";
import { useQuery } from "react-query";
import axios from "axios";
 
// helper for “closed/no meals”
const isClosedDiningCommons = (error) => {
  if (!error) return false;
  const status = error.response?.status;
  const rawMessage = error.response?.data?.message;
  const msg = typeof rawMessage === "string" ? rawMessage.toLowerCase() : "";
  return status === 404 || status === 500 || msg.includes("no meals");
};
 
export default function DiningCommonsTable({ commons, date }) {
  const testid = "DiningCommonsTable";
 
  function MealsCell({ row }) {
    const code = row.original.code;
    const url = `/api/diningcommons/${date}/${code}`;
 
    const { data, error, status } = useQuery(
      [url],
      async () => (await axios.get(url)).data,
      {
        initialData: [],
        retry: false,
        onError: (err) =>
          console.error(`Error loading meals for ${code} on ${date}`, err),
      },
    );
 
    if (status === "loading") return <span>...</span>;
 
    // if closed or error -> just say no meals offered
    if (status === "error" || isClosedDiningCommons(error)) {
      return <span>no meals offered</span>;
    }
 
    // normalize meals
    let meals = Array.isArray(data)
      ? data.map((m) => m.name)
      : data?.meals?.map((m) => m.name) || [];
 
    if (meals.length === 0) return <span>no meals offered</span>;
 
    return (
      <>
        {meals.map((meal) => {
          const label =
            meal.charAt(0).toUpperCase() + meal.slice(1).toLowerCase();
          const to = `/diningcommons/${date}/${code}/${meal}`;
          return (
            <Link key={meal} to={to} style={{ marginRight: "0.75rem" }}>
              {label}
            </Link>
          );
        })}
      </>
    );
  }
 
  const columns = [
    {
      Header: "Code",
      accessor: "code",
      Cell: ({ value }) => (
        <Link to={`/diningcommons/${date}/${value}`}>{value}</Link>
      ),
    },
    { Header: "Name", accessor: "name" },
    {
      Header: "Meals Offered Today",
      accessor: "meals",
      Cell: (props) => <MealsCell {...props} />,
    },
    {
      Header: "Has Dining Cam",
      accessor: "hasDiningCam",
      Cell: ({ value }) => (value ? "✅" : "❌"),
    },
    {
      Header: "Has Sack Meal",
      accessor: "hasSackMeal",
      Cell: ({ value }) => (value ? "✅" : "❌"),
    },
    {
      Header: "Has Takeout Meal",
      accessor: "hasTakeoutMeal",
      Cell: ({ value }) => (value ? "✅" : "❌"),
    },
  ];
 
  return <OurTable data={commons} columns={columns} testid={testid} />;
}