All files / pages/ReviewsPage CreateReviewsPage.js

100% Statements 44/44
100% Branches 28/28
100% Functions 5/5
100% Lines 44/44

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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127                    40x 40x 40x 40x 40x 40x   40x 40x     40x 24x 18x 18x 18x     15x   10x 10x   18x       18x       40x   16x         16x 1x 1x     15x   15x 15x                 15x 15x       9x 8x 8x   8x   8x         8x 5x     7x 7x 7x 1x   6x         40x           40x 17x                   23x                            
import React, { useState, useEffect } from "react";
import { useParams, useNavigate, useLocation } from "react-router-dom";
import axios from "axios";
import { toast } from "react-toastify";
 
import BasicLayout from "main/layouts/BasicLayout/BasicLayout";
import ReviewForm from "main/components/MenuItemReviews/ReviewForm";
import { useCurrentUser } from "main/utils/currentUser";
 
export default function CreateReviewPage({ id: idFromProps }) {
  const { id: idFromRoute } = useParams();
  const id = idFromProps ?? idFromRoute;
  const { data: currentUser } = useCurrentUser();
  const navigate = useNavigate();
  const location = useLocation();
  const from = location.state?.from || "/reviews/create";
 
  const [itemName, setItemName] = useState("");
  const [isLoadingItem, setIsLoadingItem] = useState(!!id);
 
  // Fetch item name if we have an ID
  useEffect(() => {
    if (id) {
      const fetchItemName = async () => {
        try {
          const response = await axios.get(
            `/api/diningcommons/menuitem?id=${id}`,
          );
          setItemName(response.data.name || `Menu Item #${id}`);
        } catch (error) {
          console.error("Error fetching item:", error);
          setItemName(`Menu Item #${id}`);
        } finally {
          setIsLoadingItem(false);
        }
      };
 
      fetchItemName();
    }
  }, [id]);
 
  const submitAction = async (formData) => {
    const reviewerEmail =
      currentUser &&
      currentUser.root &&
      currentUser.root.user &&
      currentUser.root.user.email;
 
    if (!reviewerEmail) {
      toast.error("You must be logged in to submit a review.");
      return;
    }
 
    const itemId = id ? parseInt(id, 10) : parseInt(formData.itemId, 10);
 
    try {
      const payload = {
        reviewerEmail,
        itemsStars: parseInt(formData.stars, 10),
        reviewerComments: formData.comments,
        dateItemServed: formData.dateServed, // Use the date from the form
        itemId,
      };
 
      // Stryker disable next-line all
      const REVIEW_POST_URL = "/api/reviews/post";
      const response = await axios.post(REVIEW_POST_URL, null, {
        params: payload,
      });
 
      const review = response.data;
      const displayName = review.item?.name || itemName;
      const rating = review.itemsStars;
      const comment =
        review.reviewerComments?.trim() || "No comments provided.";
 
      toast.success(
        `✅ Review submitted for "${displayName}"\n⭐ Rating: ${rating}\n💬 Comment: ${comment}`,
        { autoClose: 8000 },
      );
 
      setTimeout(() => {
        navigate(from);
      }, 1000);
    } catch (e) {
      console.error(e);
      const message = e.response?.data?.message || e.response?.data?.error;
      if (e.response?.status === 404 && message.includes("MenuItem")) {
        toast.error(`Menu item with ID ${itemId} not found.`);
      } else {
        toast.error("Error creating review.");
      }
    }
  };
 
  const initialContents = {
    stars: "",
    comments: "",
    dateServed: "", // Initialize the date field
  };
 
  if (isLoadingItem) {
    return (
      <BasicLayout>
        <div className="pt-2">
          <h1>Leave a Review</h1>
          <p>Loading item information...</p>
        </div>
      </BasicLayout>
    );
  }
 
  return (
    <BasicLayout>
      <div className="pt-2">
        <h1>Leave a Review</h1>
        <ReviewForm
          initialContents={initialContents}
          submitAction={submitAction}
          buttonLabel="Submit Review"
          itemName={itemName}
        />
      </div>
    </BasicLayout>
  );
}