GTBitsOfGood / heart-of-passion

Retreat Planning Tool for Heart of Passion
MIT License
5 stars 0 forks source link

[Ignore] Open Text Box #123

Closed jaynagpaul closed 3 months ago

jaynagpaul commented 3 months ago

Description We've done a really great job this semester, and the product has made ENORMOUS improvements from its initial state. Now its time to polish it up and put on the final set of bug fixes and changes.

This ticket will be focused on improving interactions with various modals across the platform, including Fundraising, Retreat Planning, Retreat Expenses, and Donor modals.

Specifically, we want each modal to have an open text box for notes that is persisted into the database.

Acceptance Criteria

jaynagpaul commented 3 months ago

samrat help

samrat-bot-app[bot] commented 3 months ago

Generating how-to...

samrat-bot-app[bot] commented 3 months ago

Hi Samrat! I'm excited to help you implement the ticket you've been given. Based on the provided codebase, here's what I would suggest:

  1. Ignore files:

    • next-env.d.ts: This file should not be edited as it is automatically generated.
    • app.d.ts: This file sets up the TypeScript types for the Lucia authentication library. It should not be edited.
    • tailwind.config.ts: This file configures the Tailwind CSS styles. You can modify it if you need to extend or overwrite the default styles.
  2. Relevant files to edit:

    • src/components/NewTextBoxModal.tsx: This is where you should implement the new text box functionality.

Here's the code for the NewTextBoxModal.tsx file:

import {
  Box,
  Button,
  FormControl,
  FormErrorMessage,
  FormLabel,
  Input,
  Modal,
  ModalBody,
  ModalCloseButton,
  ModalContent,
  ModalFooter,
  ModalHeader,
  ModalOverlay,
  VStack,
  useDisclosure,
} from "@chakra-ui/react";
import { useState } from "react";
import { trpc } from "~/utils/api";

type NewTextBoxProps = {
  isOpen: boolean;
  onClose: () => void;
};

export const NewTextBoxModal = ({ isOpen, onClose }: NewTextBoxProps) => {
  const [text, setText] = useState("");
  const [textError, setTextError] = useState(false);

  const {
    isOpen: isError,
    onClose: onCloseError,
    onOpen: onOpenError,
  } = useDisclosure({ defaultIsOpen: false });

  const trpcUtils = trpc.useUtils();
  const createTextBox = trpc.textBox.createTextBox.useMutation({
    onSuccess: () => {
      trpcUtils.textBox.invalidate();
    },
  });

  const onCloseModal = () => {
    setText("");
    setTextError(false);
    onClose();
  };

  const handleTextChange = (event: React.FormEvent<HTMLInputElement>) =>
    setText(event.currentTarget.value);

  const handleSave = async () => {
    if (!validateFields()) {
      return false;
    }
    await createTextBox.mutate(text);
    onCloseModal();
    return true;
  };

  const validateFields = () => {
    let valid = true;

    if (text === "") {
      setTextError(true);
      onOpenError();
      valid = false;
    } else {
      setTextError(false);
      onCloseError();
    }
    return valid;
  };

  return (
    <Modal isOpen={isOpen} onClose={onCloseModal} isCentered>
      <ModalOverlay />
      <ModalContent
        width="327px"
        maxWidth="327px"
        height="195px"
        borderRadius="none"
        boxShadow={"0px 4px 29px 0px #00000040"}
      >
        <ModalHeader />
        <ModalCloseButton
          borderRadius="50%"
          outline="solid"
          width="28px"
          height="28px"
        />
        <ModalBody pl="33px" pr="33px" lineHeight="24px">
          <VStack
            fontFamily="body"
            fontSize="16px"
            fontWeight="light"
            alignItems="start"
            spacing="5px"
          >
            <FormControl isInvalid={textError}>
              <FormLabel textColor="black" fontWeight="600" mb="4px">
                Text
              </FormLabel>
              <Input
                placeholder="Enter text"
                color="#666666"
                _placeholder={{ color: "#666666" }}
                border="1px solid #D9D9D9"
                borderRadius="0px"
                width="240px"
                height="30px"
                value={text}
                onChange={handleTextChange}
              />
              <Box minHeight="20px" mt={2}>
                <FormErrorMessage mt={0}>Text is required</FormErrorMessage>
              </Box>
            </FormControl>
          </VStack>
        </ModalBody>

        <ModalFooter pr="54px" pb="26px" pt="0px">
          <Button
            colorScheme="twitter"
            bg="hop_blue.500"
            onClick={handleSave}
            fontFamily="oswald"
            fontSize="20px"
            fontWeight="400"
          >
            APPLY
          </Button>
        </ModalFooter>
        {isError && <FloatingAlert onClose={onCloseError} />}
      </ModalContent>
    </Modal>
  );
};

This implementation includes the following:

  1. A NewTextBoxModal component that renders a modal with a text input field and a save button.
  2. The modal has state for the text input and an error state to handle validation.
  3. The handleSave function is responsible for validating the input and saving the text box using the createTextBox mutation.
  4. The onCloseModal function resets the state and closes the modal.
  5. The FloatingAlert component is used to display an error message if the text input is empty.

You may need to add the necessary tRPC routes and mutations to handle the creation of the text box. Additionally, you should integrate this new NewTextBoxModal component into your application where appropriate.

Let me know if you have any questions or if there's anything else I can assist you with!

SamratSahoo commented 3 months ago

this is kinda insane ngl