refactor(frontend): replace Temp components with design system components (#12158)

This commit is contained in:
Nhan Nguyen 2025-12-25 13:53:55 -05:00 committed by GitHub
parent a51b285021
commit 89a9e73c8a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 105 additions and 109 deletions

View File

@ -19,32 +19,14 @@ import { SettingsDropdownInput } from "../settings/settings-dropdown-input";
import { I18nKey } from "#/i18n/declaration";
import { useSettingsNavItems } from "#/hooks/use-settings-nav-items";
import DocumentIcon from "#/icons/document.svg?react";
import { Divider } from "#/ui/divider";
import { ContextMenuListItem } from "../context-menu/context-menu-list-item";
interface TempButtonProps {
start: React.ReactNode;
onClick: () => void;
}
function TempButton({
start,
children,
onClick,
}: React.PropsWithChildren<TempButtonProps>) {
return (
<button
type="button"
onClick={onClick}
className="flex items-center gap-1 cursor-pointer hover:text-white w-full text-left"
>
{start}
{children}
</button>
);
}
function TempDivider() {
return <div className="h-[1px] w-full bg-[#5C5D62] my-1.5" />;
}
// Shared className for context menu list items in the user context menu
// Removes default padding and hover background to match the simpler text-hover style
const contextMenuListItemClassName = cn(
"flex items-center p-0 h-auto hover:bg-transparent hover:text-white gap-1",
);
interface UserContextMenuProps {
type: OrganizationUserRole;
@ -140,31 +122,34 @@ export function UserContextMenu({ type, onClose }: UserContextMenuProps) {
{!isUser && (
<>
<TempButton
<ContextMenuListItem
onClick={handleInviteMemberClick}
start={<IoPersonAddOutline className="text-white" size={14} />}
className={contextMenuListItemClassName}
>
<IoPersonAddOutline className="text-white" size={14} />
{t(I18nKey.ORG$INVITE_ORGANIZATION_MEMBER)}
</TempButton>
</ContextMenuListItem>
<TempDivider />
<Divider className="my-1.5" />
<TempButton
<ContextMenuListItem
onClick={handleManageAccountClick}
start={<IoCardOutline className="text-white" size={14} />}
className={contextMenuListItemClassName}
>
<IoCardOutline className="text-white" size={14} />
{t(I18nKey.ORG$MANAGE_ACCOUNT)}
</TempButton>
<TempButton
</ContextMenuListItem>
<ContextMenuListItem
onClick={handleManageOrganizationMembersClick}
start={<IoPersonOutline className="text-white" size={14} />}
className={contextMenuListItemClassName}
>
<IoPersonOutline className="text-white" size={14} />
{t(I18nKey.ORG$MANAGE_ORGANIZATION_MEMBERS)}
</TempButton>
</ContextMenuListItem>
</>
)}
<TempDivider />
<Divider className="my-1.5" />
{navItems.map((item) => (
<Link
@ -182,7 +167,7 @@ export function UserContextMenu({ type, onClose }: UserContextMenuProps) {
</Link>
))}
<TempDivider />
<Divider className="my-1.5" />
<a
href="https://docs.openhands.dev"
@ -195,12 +180,13 @@ export function UserContextMenu({ type, onClose }: UserContextMenuProps) {
{t(I18nKey.SIDEBAR$DOCS)}
</a>
<TempButton
<ContextMenuListItem
onClick={handleLogout}
start={<IoLogOutOutline className="text-white" size={14} />}
className={contextMenuListItemClassName}
>
<IoLogOutOutline className="text-white" size={14} />
{t(I18nKey.ACCOUNT_SETTINGS$LOGOUT)}
</TempButton>
</ContextMenuListItem>
</div>
</div>
);

View File

@ -21,66 +21,8 @@ import { I18nKey } from "#/i18n/declaration";
import { amountIsValid } from "#/utils/amount-is-valid";
import { useUpdateOrganization } from "#/hooks/mutation/use-update-organization";
import { useDeleteOrganization } from "#/hooks/mutation/use-delete-organization";
function TempChip({
children,
...props
}: React.PropsWithChildren<{ "data-testid": string }>) {
return (
<div
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
style={{ minWidth: "100px" }}
data-openhands-chip
className="bg-[#FFE165] px-4 rounded-[100px] text-black text-lg text-center font-semibold"
>
{children}
</div>
);
}
interface TempInteractiveChipProps {
onClick: () => void;
}
function TempInteractiveChip({
children,
onClick,
}: React.PropsWithChildren<TempInteractiveChipProps>) {
return (
<div
onClick={onClick}
className="bg-[#E4E4E4] px-2 rounded-[100px] text-black text-sm text-center font-semibold cursor-pointer"
>
{children}
</div>
);
}
function TempButton({
children,
onClick,
type,
variant = "primary",
}: React.PropsWithChildren<{
onClick?: () => void;
type: "button" | "submit";
variant?: "primary" | "secondary";
}>) {
return (
<button
className={cn(
"flex-1 py-3 rounded text-sm text-center font-semibold cursor-pointer",
variant === "primary" && "bg-[#F3CE49] text-black",
variant === "secondary" && "bg-[#737373] text-white",
)}
type={type === "submit" ? "submit" : "button"}
onClick={onClick}
>
{children}
</button>
);
}
import { CreditsChip } from "#/ui/credits-chip";
import { InteractiveChip } from "#/ui/interactive-chip";
interface ChangeOrgNameModalProps {
onClose: () => void;
@ -252,10 +194,17 @@ function AddCreditsModal({ onClose }: AddCreditsModalProps) {
</div>
<div className="flex gap-2">
<TempButton type="submit">{t(I18nKey.ORG$NEXT)}</TempButton>
<TempButton type="button" onClick={onClose} variant="secondary">
<BrandButton type="submit" variant="primary" className="flex-1 py-3">
{t(I18nKey.ORG$NEXT)}
</BrandButton>
<BrandButton
type="button"
onClick={onClose}
variant="secondary"
className="flex-1 py-3"
>
{t(I18nKey.BUTTON$CANCEL)}
</TempButton>
</BrandButton>
</div>
</form>
</ModalBackdrop>
@ -323,15 +272,13 @@ function ManageOrg() {
{t(I18nKey.ORG$CREDITS)}
</span>
<div className="flex items-center gap-2">
<TempChip data-testid="available-credits">
<CreditsChip testId="available-credits">
{organization?.credits}
</TempChip>
</CreditsChip>
{canAddCredits && (
<TempInteractiveChip
onClick={() => setAddCreditsFormVisible(true)}
>
<InteractiveChip onClick={() => setAddCreditsFormVisible(true)}>
{t(I18nKey.ORG$ADD)}
</TempInteractiveChip>
</InteractiveChip>
)}
</div>
</div>

View File

@ -0,0 +1,30 @@
import { cn } from "#/utils/utils";
interface CreditsChipProps {
testId?: string;
className?: string;
}
/**
* Chip component for displaying credits amount
* Uses yellow background with black text for visibility
*/
export function CreditsChip({
children,
testId,
className,
}: React.PropsWithChildren<CreditsChipProps>) {
return (
<div
data-testid={testId}
data-openhands-chip
style={{ minWidth: "100px" }}
className={cn(
"bg-[#FFE165] px-4 rounded-[100px] text-black text-lg text-center font-semibold",
className,
)}
>
{children}
</div>
);
}

View File

@ -0,0 +1,33 @@
import { cn } from "#/utils/utils";
interface InteractiveChipProps {
onClick: () => void;
testId?: string;
className?: string;
}
/**
* Small clickable chip component for actions like "Add"
* Uses gray background with black text
*/
export function InteractiveChip({
children,
onClick,
testId,
className,
}: React.PropsWithChildren<InteractiveChipProps>) {
return (
<button
type="button"
data-testid={testId}
onClick={onClick}
className={cn(
"bg-[#E4E4E4] px-2 rounded-[100px] text-black text-sm text-center font-semibold cursor-pointer",
"hover:bg-[#D4D4D4] transition-colors",
className,
)}
>
{children}
</button>
);
}