Open Source Contribution(w. Codu)
Published: 2023-11-23 01:17:07

### Intro 

Through `Hacktoberfest`, I got to know the open-source project [Codu](https://github.com/codu-code/codu), and I'm one of the contributors of Codu and I keep working on the project. This project is written in `Typescript` and `Nextjs`, so there are lots of things to learn through the contribution. 


### Issue
I started working on [the issue](https://github.com/codu-code/codu/issues/594) 3weeks ago, but I recently could wrap it up and it took some time than I expected. 

The issue was to fix the open menu on the `Article Sidebar` when clicked. 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wbpks1vytzqkizc2dw72.png)

If you clicked `Report Article`, then the modal would pop up, but the menu still remained. 

### Investigate

First, I looked into the code, and found out they used [Headless UI](https://headlessui.com/react/popover) to use `Popover` component. Basically, the `Popover` doesn't close the menu because it is their one of attributes, so `Menu` Component should have used instead of `Popover`.


### How to fix

After investigation, I found two ways of refactoring code, one is to use `Menu` component and the other is to close `Popover` manually. However, the first way needs lots of time and effort and I didn't want to modify the existing codes. 

```ts
import { Popover } from '@headlessui/react'
import MyLink from './MyLink'

function MyPopover() {
  return (
    <Popover>
      <Popover.Button>Solutions</Popover.Button>
      <Popover.Panel>
        <Popover.Button as={MyLink} href="/insights">
          Insights
        </Popover.Button>
        {/* ... */}
      </Popover.Panel>
    </Popover>
  )
}
```
Thus, I easily used `Popover.Button` between `Popover.Panel`, and when I clicked the `Report Article`, the menu was gone as I expected, but unfortunately, `Report Modal` also disappeared in a second. 


```ts
 const [isPopoverPanelOpen, setIsPopoverPanelOpen] = useState(true);

  const [isPopoverPanelOpen, setIsPopoverPanelOpen] = useState(true);

  const closePopoverPanel = (e: React.FormEvent) => {
    e.preventDefault();
    setIsPopoverPanelOpen(false);
  };

  const openPopoverPanel = () => {
    setIsPopoverPanelOpen(true);
  };
            <Popover className="ml-4 relative">
            <Popover.Button
              onClick={openPopoverPanel}
              className="rounded-full p-1 hover:bg-neutral-300 dark:hover:bg-neutral-800"
            >
              <span className="sr-only">Open user menu</span>
              <DotsHorizontalIcon className="h-6 w-6" />
            </Popover.Button>
            <Transition
              as={Fragment}
              enter="transition ease-out duration-100"
              enterFrom="transform opacity-0 scale-95"
              enterTo="transform opacity-100 scale-100"
              leave="transition ease-in duration-75"
              leaveFrom="transform opacity-100 scale-100"
              leaveTo="transform opacity-0 scale-95"
            >
              <Popover.Panel
                className={`origin-top-right absolute bottom-14 right-0 lg:left-16 lg:bottom-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white dark:bg-white ring-1 px-1 ring-black ring-opacity-5 focus:outline-none 
                ${isPopoverPanelOpen ? "" : "hidden"}`}
              >
                <div>
                  <ul>
                    <li className="block rounded px-4 py-2 text-neutral-900 hover:bg-neutral-200 dark:text-neutral-700">
                      <a
                        href={`https://twitter.com/intent/tweet?text="${postTitle}", by ${postUsername}&hashtags=coducommunity,codu&url=${postUrl}`}
                      >
                        Share to X
                      </a>
                    </li>
                    <li>
                      <a
                        className="block rounded px-4 py-2 text-neutral-900 hover:bg-neutral-200 dark:text-neutral-700"
                        href={`https://www.linkedin.com/sharing/share-offsite/?url=${postUrl}`}
                      >
                        Share to LinkedIn
                      </a>
                    </li>
                    <li>
                      <button
                        className="block w-full rounded px-4 py-2 text-left text-neutral-900 hover:bg-neutral-200 dark:text-neutral-700"
                        onClick={handleCopyToClipboard}
                      >
                        {label}
                      </button>
                    </li>
                    <li className="block px-4 py-2 text-neutral-900 dark:text-neutral-700 hover:bg-neutral-200 rounded">
                      <button onClick={closePopoverPanel}>
                        <ReportModal
                          type="post"
                          title={postTitle}
                          id={postId}
                        />
                      </button>
                    </li>
                  </ul>
                </div>
              </Popover.Panel>
            </Transition>
          </Popover>
```
Eventually, I could use another workaround to close the menu while the report modal is open. I created a button with `closePopoverPanel` function and this updates `isPopoverPanelOpen` value as false and it closes the menu. And when `Popover.Button` is clicked it updates `isPopoverPanelOpen` value as true vice versa. Now, the component can show and hide the menu when `Report Article` is clicked. This is my [PR](https://github.com/codu-code/codu/pull/615).


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ske6uv4omdnia8wbt3ei.png)