Skip to content

Commit 31dbce4

Browse files
committed
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
1 parent a871f56 commit 31dbce4

File tree

1 file changed

+64
-36
lines changed

1 file changed

+64
-36
lines changed

app/changelog/buildComponent.tsx

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import Build from "../../types/build";
22
import Change from "../../types/change";
33
import ChangeComponent from "./changeComponent";
4-
import React, { useState } from "react";
4+
import React, {useEffect, useRef, useState} from "react";
55
import Panel from "../common/uiLibrary/panel";
6+
import Button from "../common/uiLibrary/Button";
7+
import {BiSolidChevronDown} from "react-icons/bi";
8+
import classNames from "classnames";
69

710
function populateChangeList(changes: Change[]) {
811
let changesList;
@@ -35,10 +38,12 @@ interface BuildProps {
3538
build: Build
3639
}
3740

38-
const BuildComponent = (props: BuildProps) => {
39-
const { version_number, date_created, changes } = props.build;
40-
const changesList = populateChangeList(changes);
41-
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
41+
//TODO: make this component a general dropdown instead and move it to commons
42+
const DownloadBuildDropdown = (props: { version: string }) => {
43+
'use client'
44+
45+
const [isOpen, setIsOpen] = useState(false);
46+
const dropdownRef = useRef<HTMLDivElement>(null);
4247

4348
const platforms = [
4449
"linuxserver",
@@ -47,39 +52,60 @@ const BuildComponent = (props: BuildProps) => {
4752
"StandaloneWindows64"
4853
];
4954

50-
const renderDownloadSection = () => {
51-
return (
52-
<div className="relative mt-2 flex justify-end">
53-
<button
54-
onClick={toggleDropdown}
55-
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-4 rounded"
56-
>
57-
Download
58-
</button>
59-
{isDropdownOpen && (
60-
<div className="absolute right-0 mt-12 w-56 rounded-md shadow-lg bg-slate-600 ring-1 ring-black ring-opacity-5">
61-
<div className="py-1" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
62-
{platforms.map((platform) => (
63-
<a
64-
key={platform}
65-
href={`https://unitystationfile.b-cdn.net/UnityStationDevelop/${platform}/${version_number}.zip`}
66-
className="block px-4 py-2 text-sm text-blue-50 hover:bg-gray-100 hover:text-gray-900"
67-
role="menuitem"
68-
>
69-
{platform}
70-
</a>
71-
))}
72-
</div>
73-
</div>
74-
)}
75-
</div>
76-
);
77-
};
55+
const listClasses = classNames(
56+
'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',
57+
{
58+
'opacity-100 translate-y-0': isOpen,
59+
'opacity-0 -translate-y-4 pointer-events-none': !isOpen
60+
}
61+
);
7862

79-
const toggleDropdown = () => {
80-
setIsDropdownOpen(!isDropdownOpen);
63+
const handleClick = () => {
64+
setIsOpen(!isOpen);
65+
}
66+
67+
const handleClickOutside = (event: MouseEvent) => {
68+
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
69+
setIsOpen(false);
70+
}
8171
};
8272

73+
useEffect(() => {
74+
if (isOpen) {
75+
document.addEventListener('mousedown', handleClickOutside);
76+
} else {
77+
document.removeEventListener('mousedown', handleClickOutside);
78+
}
79+
return () => document.removeEventListener('mousedown', handleClickOutside);
80+
}, [isOpen]);
81+
82+
return (
83+
<div className="relative" ref={dropdownRef}>
84+
<Button upperCase={false} iconRight={BiSolidChevronDown} onClick={handleClick}>
85+
Download
86+
</Button>
87+
<div className={listClasses}>
88+
<div className="py-1" role="menu" aria-orientation="vertical" aria-labelledby="options-menu">
89+
{platforms.map((platform) => (
90+
<a
91+
key={platform}
92+
href={`https://unitystationfile.b-cdn.net/UnityStationDevelop/${platform}/${props.version}.zip`}
93+
className="block px-4 py-2 text-sm text-blue-50 hover:bg-gray-100 hover:text-gray-900"
94+
role="menuitem"
95+
>
96+
{platform}
97+
</a>
98+
))}
99+
</div>
100+
</div>
101+
</div>
102+
);
103+
}
104+
105+
const BuildComponent = (props: BuildProps) => {
106+
const { version_number, date_created, changes } = props.build;
107+
const changesList = populateChangeList(changes);
108+
83109
return (
84110
<Panel>
85111
<div className='flex justify-between'>
@@ -95,7 +121,9 @@ const BuildComponent = (props: BuildProps) => {
95121
{changesList}
96122
</ul>
97123
</div>
98-
{renderDownloadSection()}
124+
<div className='relative mt-2 flex justify-end'>
125+
<DownloadBuildDropdown version={version_number} />
126+
</div>
99127
</Panel>
100128
)
101129
}

0 commit comments

Comments
 (0)