From 31dbce4e84179501204734968c4fa1f90212b2bd Mon Sep 17 00:00:00 2001 From: Gilles <43683714+corp-0@users.noreply.github.com> Date: Sun, 27 Oct 2024 18:14:12 -0300 Subject: [PATCH] refactor: revise Max's changes for new download dropdown Eventually we have to make this component a general component that can be used anywhere else in the site --- app/changelog/buildComponent.tsx | 100 ++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 36 deletions(-) diff --git a/app/changelog/buildComponent.tsx b/app/changelog/buildComponent.tsx index c2948d6..f2f7cf4 100644 --- a/app/changelog/buildComponent.tsx +++ b/app/changelog/buildComponent.tsx @@ -1,8 +1,11 @@ import Build from "../../types/build"; import Change from "../../types/change"; import ChangeComponent from "./changeComponent"; -import React, { useState } from "react"; +import React, {useEffect, useRef, useState} from "react"; import Panel from "../common/uiLibrary/panel"; +import Button from "../common/uiLibrary/Button"; +import {BiSolidChevronDown} from "react-icons/bi"; +import classNames from "classnames"; function populateChangeList(changes: Change[]) { let changesList; @@ -35,10 +38,12 @@ interface BuildProps { build: Build } -const BuildComponent = (props: BuildProps) => { - const { version_number, date_created, changes } = props.build; - const changesList = populateChangeList(changes); - const [isDropdownOpen, setIsDropdownOpen] = useState(false); +//TODO: make this component a general dropdown instead and move it to commons +const DownloadBuildDropdown = (props: { version: string }) => { + 'use client' + + const [isOpen, setIsOpen] = useState(false); + const dropdownRef = useRef(null); const platforms = [ "linuxserver", @@ -47,39 +52,60 @@ const BuildComponent = (props: BuildProps) => { "StandaloneWindows64" ]; - const renderDownloadSection = () => { - return ( -
- - {isDropdownOpen && ( -
-
- {platforms.map((platform) => ( - - {platform} - - ))} -
-
- )} -
- ); - }; + const listClasses = classNames( + 'absolute top-full mt-2 w-56 rounded-md shadow-lg bg-slate-600 ring-1 ring-black ring-opacity-5 transition-opacity transition-transform duration-500 ease-out', + { + 'opacity-100 translate-y-0': isOpen, + 'opacity-0 -translate-y-4 pointer-events-none': !isOpen + } + ); - const toggleDropdown = () => { - setIsDropdownOpen(!isDropdownOpen); + const handleClick = () => { + setIsOpen(!isOpen); + } + + const handleClickOutside = (event: MouseEvent) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setIsOpen(false); + } }; + useEffect(() => { + if (isOpen) { + document.addEventListener('mousedown', handleClickOutside); + } else { + document.removeEventListener('mousedown', handleClickOutside); + } + return () => document.removeEventListener('mousedown', handleClickOutside); + }, [isOpen]); + + return ( +
+ +
+
+ {platforms.map((platform) => ( + + {platform} + + ))} +
+
+
+ ); +} + +const BuildComponent = (props: BuildProps) => { + const { version_number, date_created, changes } = props.build; + const changesList = populateChangeList(changes); + return (
@@ -95,7 +121,9 @@ const BuildComponent = (props: BuildProps) => { {changesList}
- {renderDownloadSection()} +
+ +
) }