mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
fix(frontend): prevent Wallet rendering twice (#11282)
## Changes 🏗️ The `<Wallet />` was being rendered twice ( one hidden with CSS `hidden` ) because of the Navbar layout, which caused logic issues within the wallet. I changed to render it conditionally via Javascript instance, which is always better practice than use `hidden` specially for components with actual logic. I also moved the component files closer to where it is used ( in the navbar ). I have a Cursor plugin that removes imports when unused, but annoyingly re-organizes them, hence the changes around that... ## Checklist 📋 ### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Login - [x] There is only 1 Wallet in the DOM
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
import { useToast } from "@/components/molecules/Toast/use-toast";
|
||||
import { useTurnstile } from "@/hooks/useTurnstile";
|
||||
import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
|
||||
import { environment } from "@/services/environment";
|
||||
import { loginFormSchema, LoginProvider } from "@/types/auth";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import z from "zod";
|
||||
import { useToast } from "@/components/molecules/Toast/use-toast";
|
||||
import { environment } from "@/services/environment";
|
||||
|
||||
export function useLoginPage() {
|
||||
const { supabase, user, isUserLoading } = useSupabase();
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { useGetV2GetUserProfile } from "@/app/api/__generated__/endpoints/store/store";
|
||||
import { IconAutoGPTLogo, IconType } from "@/components/__legacy__/ui/icons";
|
||||
import Wallet from "../../../../app/(no-navbar)/onboarding/components/Wallet/Wallet";
|
||||
import { useBreakpoint } from "@/lib/hooks/useBreakpoint";
|
||||
import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
|
||||
import { getAccountMenuItems, loggedInLinks, loggedOutLinks } from "../helpers";
|
||||
import { AccountMenu } from "./AccountMenu/AccountMenu";
|
||||
import { AgentActivityDropdown } from "./AgentActivityDropdown/AgentActivityDropdown";
|
||||
import { LoginButton } from "./LoginButton";
|
||||
import { MobileNavBar } from "./MobileNavbar/MobileNavBar";
|
||||
import { NavbarLink } from "./NavbarLink";
|
||||
import { getAccountMenuItems, loggedInLinks, loggedOutLinks } from "../helpers";
|
||||
import { useGetV2GetUserProfile } from "@/app/api/__generated__/endpoints/store/store";
|
||||
import { AgentActivityDropdown } from "./AgentActivityDropdown/AgentActivityDropdown";
|
||||
import { useSupabase } from "@/lib/supabase/hooks/useSupabase";
|
||||
import { Wallet } from "./Wallet/Wallet";
|
||||
|
||||
interface NavbarViewProps {
|
||||
isLoggedIn: boolean;
|
||||
@@ -16,6 +18,10 @@ interface NavbarViewProps {
|
||||
|
||||
export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
|
||||
const { user } = useSupabase();
|
||||
const breakpoint = useBreakpoint();
|
||||
const isSmallScreen = breakpoint === "sm" || breakpoint === "base";
|
||||
const dynamicMenuItems = getAccountMenuItems(user?.role);
|
||||
|
||||
const { data: profile } = useGetV2GetUserProfile({
|
||||
query: {
|
||||
select: (res) => (res.status === 200 ? res.data : null),
|
||||
@@ -23,21 +29,29 @@ export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
|
||||
},
|
||||
});
|
||||
|
||||
const dynamicMenuItems = getAccountMenuItems(user?.role);
|
||||
|
||||
return (
|
||||
<>
|
||||
<nav className="sticky top-0 z-40 inline-flex h-[60px] w-full items-center border border-white/50 bg-[#f3f4f6]/20 p-3 backdrop-blur-[26px]">
|
||||
{/* Left section */}
|
||||
<div className="hidden flex-1 items-center gap-3 md:flex md:gap-5">
|
||||
{isLoggedIn
|
||||
? loggedInLinks.map((link) => (
|
||||
<NavbarLink key={link.name} name={link.name} href={link.href} />
|
||||
))
|
||||
: loggedOutLinks.map((link) => (
|
||||
<NavbarLink key={link.name} name={link.name} href={link.href} />
|
||||
))}
|
||||
</div>
|
||||
{!isSmallScreen ? (
|
||||
<div className="flex flex-1 items-center gap-3 gap-5">
|
||||
{isLoggedIn
|
||||
? loggedInLinks.map((link) => (
|
||||
<NavbarLink
|
||||
key={link.name}
|
||||
name={link.name}
|
||||
href={link.href}
|
||||
/>
|
||||
))
|
||||
: loggedOutLinks.map((link) => (
|
||||
<NavbarLink
|
||||
key={link.name}
|
||||
name={link.name}
|
||||
href={link.href}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{/* Centered logo */}
|
||||
<div className="static h-auto w-[4.5rem] md:absolute md:left-1/2 md:top-1/2 md:w-[5.5rem] md:-translate-x-1/2 md:-translate-y-1/2">
|
||||
@@ -45,11 +59,11 @@ export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
|
||||
</div>
|
||||
|
||||
{/* Right section */}
|
||||
{isLoggedIn ? (
|
||||
<div className="hidden flex-1 items-center justify-end gap-4 md:flex">
|
||||
{isLoggedIn && !isSmallScreen ? (
|
||||
<div className="flex flex-1 items-center justify-end gap-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<AgentActivityDropdown />
|
||||
{profile && <Wallet />}
|
||||
{profile && <Wallet key={profile.username} />}
|
||||
<AccountMenu
|
||||
userName={profile?.username}
|
||||
userEmail={profile?.name}
|
||||
@@ -58,17 +72,17 @@ export const NavbarView = ({ isLoggedIn }: NavbarViewProps) => {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
) : !isLoggedIn ? (
|
||||
<div className="flex w-full items-center justify-end">
|
||||
<LoginButton />
|
||||
</div>
|
||||
)}
|
||||
) : null}
|
||||
{/* <ThemeToggle /> */}
|
||||
</nav>
|
||||
{/* Mobile Navbar - Adjust positioning */}
|
||||
<>
|
||||
{isLoggedIn ? (
|
||||
<div className="fixed right-0 top-2 z-50 flex items-center gap-0 md:hidden">
|
||||
{isLoggedIn && isSmallScreen ? (
|
||||
<div className="fixed right-0 top-2 z-50 flex items-center gap-0">
|
||||
<Wallet />
|
||||
<MobileNavBar
|
||||
userName={profile?.username}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
"use client";
|
||||
|
||||
import useCredits from "@/hooks/useCredits";
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/__legacy__/ui/popover";
|
||||
import { X } from "lucide-react";
|
||||
import { Text } from "@/components/atoms/Text/Text";
|
||||
import { PopoverClose } from "@radix-ui/react-popover";
|
||||
import { TaskGroups } from "@/app/(no-navbar)/onboarding/components/Wallet/components/WalletTaskGroups";
|
||||
import { ScrollArea } from "../../../../../components/__legacy__/ui/scroll-area";
|
||||
import { useOnboarding } from "@/providers/onboarding/onboarding-provider";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import * as party from "party-js";
|
||||
import WalletRefill from "./components/WalletRefill";
|
||||
import useCredits from "@/hooks/useCredits";
|
||||
import { OnboardingStep } from "@/lib/autogpt-server-api";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useOnboarding } from "@/providers/onboarding/onboarding-provider";
|
||||
import { Flag, useGetFlag } from "@/services/feature-flags/use-get-flag";
|
||||
import { storage, Key as StorageKey } from "@/services/storage/local-storage";
|
||||
import { WalletIcon } from "@phosphor-icons/react";
|
||||
import { useGetFlag, Flag } from "@/services/feature-flags/use-get-flag";
|
||||
import { PopoverClose } from "@radix-ui/react-popover";
|
||||
import { X } from "lucide-react";
|
||||
import * as party from "party-js";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { ScrollArea } from "../../../../../components/__legacy__/ui/scroll-area";
|
||||
import WalletRefill from "./components/WalletRefill";
|
||||
import { TaskGroups } from "./components/WalletTaskGroups";
|
||||
|
||||
export interface Task {
|
||||
id: OnboardingStep;
|
||||
@@ -39,7 +39,7 @@ export interface TaskGroup {
|
||||
tasks: Task[];
|
||||
}
|
||||
|
||||
export default function Wallet() {
|
||||
export function Wallet() {
|
||||
const { state, updateState } = useOnboarding();
|
||||
const isPaymentEnabled = useGetFlag(Flag.ENABLE_PLATFORM_PAYMENT);
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
import {
|
||||
Tabs,
|
||||
TabsContent,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "@/components/__legacy__/ui/tabs";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
@@ -16,14 +6,24 @@ import {
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/__legacy__/ui/form";
|
||||
import { Input } from "../../../../../../components/__legacy__/ui/input";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
Tabs,
|
||||
TabsContent,
|
||||
TabsList,
|
||||
TabsTrigger,
|
||||
} from "@/components/__legacy__/ui/tabs";
|
||||
import { Input } from "@/components/atoms/Input/Input";
|
||||
import {
|
||||
useToast,
|
||||
useToastOnFail,
|
||||
} from "../../../../../../components/molecules/Toast/use-toast";
|
||||
} from "@/components/molecules/Toast/use-toast";
|
||||
import useCredits from "@/hooks/useCredits";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import Link from "next/link";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
const topUpSchema = z.object({
|
||||
amount: z
|
||||
@@ -148,6 +148,8 @@ export default function WalletRefill() {
|
||||
"mt-2 rounded-3xl border-0 bg-white py-2 pl-6 pr-4 font-sans outline outline-1 outline-zinc-300",
|
||||
"focus:outline-2 focus:outline-offset-0 focus:outline-violet-700",
|
||||
)}
|
||||
label="Amount"
|
||||
id="amount"
|
||||
type="number"
|
||||
step="1"
|
||||
{...field}
|
||||
@@ -204,6 +206,8 @@ export default function WalletRefill() {
|
||||
)}
|
||||
type="number"
|
||||
step="1"
|
||||
label="Refill when balance drops below:"
|
||||
id="threshold"
|
||||
{...field}
|
||||
/>
|
||||
<span className="absolute left-10 -translate-y-9 text-sm text-zinc-500">
|
||||
@@ -232,6 +236,8 @@ export default function WalletRefill() {
|
||||
)}
|
||||
type="number"
|
||||
step="1"
|
||||
label="Add this amount:"
|
||||
id="refillAmount"
|
||||
{...field}
|
||||
/>
|
||||
<span className="absolute left-10 -translate-y-9 text-sm text-zinc-500">
|
||||
@@ -1,12 +1,9 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { ChevronDown, Check, BadgeQuestionMark } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import * as party from "party-js";
|
||||
import { useOnboarding } from "@/providers/onboarding/onboarding-provider";
|
||||
import {
|
||||
Task,
|
||||
TaskGroup,
|
||||
} from "@/app/(no-navbar)/onboarding/components/Wallet/Wallet";
|
||||
import { BadgeQuestionMark, Check, ChevronDown } from "lucide-react";
|
||||
import * as party from "party-js";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Task, TaskGroup } from "../Wallet";
|
||||
|
||||
interface Props {
|
||||
groups: TaskGroup[];
|
||||
Reference in New Issue
Block a user