Working a the account icon in the Navbar?

We have set up a handle button to click but we getting not a function with this code within the navbar that will trigger the account button to take to the account page.

const handleButtonClick = async (value: any) => {
    const accountPageData = await fetchAccountPageData();
    console.log(accountPageData); 
    // Now you can use accountPageData
};
<Button onClick={(event) => handleButtonClick(event)}>
     Account
</Button>

Hello @xbrandonpowell,

Can you clarify how are you implementing or importing fetchAccountPageData function?

The fetchAccountPageData function is being imported and used as an asynchronous function within the handleButtonClick method of the Navbar component.

In the code snippet I provided, the fetchAccountPageData function is imported using the following statement:

const handleButtonClick = async (value: any) => {
  const accountPageData = await fetchAccountPageData();
  console.log(accountPageData); 
  // Now you can use accountPageData
};

This usage implies that the fetchAccountPageData function is expected to return a promise, and it is being awaited within the handleButtonClick method to retrieve account page data asynchronously.

Hello @xbrandonpowell,

Could you kindly provide the full code along with the function body of the fetchAccountPageData? This will enable me to offer more precise assistance with your inquiry.

/** @jsxRuntime classic */
/** @jsx jsx */
import React, { FC, useState, useEffect } from 'react'
import { BuilderComponent, builder } from '@builder.io/react'
import { useCart } from '@lib/shopify/storefront-data-hooks'
import { jsx, Box, useThemeUI, Heading, Button } from 'theme-ui'
import { useUI } from '@components/common/context'
import Image from 'next/legacy/image'

import Link from '@components/common/Link'
import { Bag } from '@components/icons'
import Searchbar from './Searchbar'

import fetchAccountPageData from '@components/common/Account'
//import Favorites from '@components/common/Favorites'

const Navbar: FC = () => {
  const [announcement, setAnnouncement] = useState()
  const { theme } = useThemeUI()
  const { navigationLinks, thirdNavigationLink, logo, openSidebar } = useUI()
  const handleButtonClick = async (value: any) => {

    const accountPageData = await fetchAccountPageData();
    console.log(accountPageData); 
    // Now you can use accountPageData
  };

  const cart = useCart()

  useEffect(() => {
    async function fetchContent() {
      const items = cart?.lineItems || []
      const anouncementContent = await builder
        .get('announcement-bar', {
          cacheSeconds: 120,
          userAttributes: {
            itemInCart: items.map((item: any) => item.variant.product.handle),
          } as any,
        })
        
        .toPromise()
      setAnnouncement(anouncementContent)
    }
    fetchContent()
  }, [cart?.lineItems])

  return (
    <React.Fragment>
      <BuilderComponent
        content={announcement}
        data={{ theme }}
        model="announcement-bar"
      />
      <Box
        as="header"
        sx={{
          margin: `0 auto`,
          maxWidth: 1920,
          py: 2,
          px: 2,
          display: 'grid',
          gridTemplateColumns: '1fr 1fr 1fr', // Three equal columns
          alignItems: 'center',
          position: 'relative',
        }}
      >
        
        {/* First Grid: Logo */}

        <Box>
          <Heading
            sx={{
              fontSize: 20,
              fontWeight: 'bold',
            }}
          >
            {logo && logo.image && (
              <Link
                href="/"
                sx={{
                  letterSpacing: -1,
                  textDecoration: `none`,
                  paddingLeft: '5px',
                }}
              >
                <Image
                  alt="Logo"
                  width={logo.width}
                  height={logo.height}
                  src={logo.image}
                ></Image>
              </Link>
            )}

            {logo && logo.text && !logo.image && (
              <Link
                href="/"
                sx={{
                  letterSpacing: -1,
                  textDecoration: `none`,
                  paddingLeft: '5px',
                }}
              >
                {logo.text}
              </Link>
            )}
          </Heading>
        </Box>

        {/* Second Grid: Navigation Links */}

        <Box
          sx={{
            display: ['none', 'none', 'flex'],
            flexBasis: 0,
            minWidth: 240,
            justifyContent: 'space-evenly',
          }}
        >
          {navigationLinks?.map((link, index) => (
            <Link key={index} sx={{ padding: 10 }} href={link.link || '//'}>
              {link.title}
            </Link>
          ))}
        </Box>

        {/* Third Grid: Navbar */}
        <Box
          sx={{
            display: 'flex',
            minWidth: 140,
            width: '100%',
            justifyContent: ['space-between', 'flex-end'],
          }}
        >
            <Searchbar />

            <div className='line'></div>

            <Button onClick={(event) => handleButtonClick(event)}>
                Account
            </Button>

            {/* <Favorites /> */}

            <Button onClick={openSidebar} aria-label="Cart">
              <Bag />
            </Button>

            <div className='line'></div>

            {thirdNavigationLink?.map((link: { link: string, title: string }, index: number) => (
              <Link key={index} sx={{ padding: 10 }} href={link.link || '/'}>
                {link.title}
              </Link>
            ))}
        </Box>
      </Box>
    </React.Fragment>
  )
}

Hello @xbrandonpowell,

Thank you for clarifying. I see the function now, can you also share ‘@components/common/Account’ code?

Just updated the code, addressed some issues, and added the ShopifyConfigResponse. However, I commented out the import of @config/shopify. My question is, why include the configuration in Shopify if it’s already imported?

/** @jsxRuntime classic */
/** @jsx jsx */

import React, { FC, useState, useEffect, useRef } from 'react';
import { useRouter } from 'next/router'
import { jsx } from '@emotion/react'
//import shopifyConfig from '@config/shopify'

interface ShopifyConfigResponse {
  domain: 'process.env.SHOPIFY_STORE_DOMAIN';
  storefrontAccessToken: 'process.env.SHOPIFY_STOREFRONT_API_TOKEN';
}

const shopifyConfig = async (configKey: string): Promise<ShopifyConfigResponse> => {
  // Implementation of fetching Shopify configuration data
  // This is just a placeholder, replace it with your actual implementation
  const response = await fetch(`/api/shopify/config/${configKey}`);
  const data = await response.json();
  return data;
};

// Define the Props interface for the Account component
interface Props {
    className?: string
    id?: string
}

// Define the Account component as a Functional Component (FC) with Props
const Account: FC<Props> = () => {
    // Get the router object from Next.js
    const router = useRouter()

    // State variables for managing the component's behavior
    const [isSwitch, setIsSwitch] = useState(false) // Toggle between login and signup forms
    const buttonRef = useRef<HTMLDivElement>(null) // Reference to the button element
    const [accountPageData, setAccountPageData] = useState<ShopifyConfigResponse | null>(null);; // Store data related to the account page

    // Effect hook to fetch data when the route changes
    useEffect(() => {
        const fetchAccountPageData = async () => {
            // Fetch account page data using the shopifyConfig function
            const data = await shopifyConfig ('account-page');
            // Set the fetched data and update the switch state
            setAccountPageData(data);
            setIsSwitch(false);
        }
        // Trigger the fetch when the route changes (excluding query parameters)
        fetchAccountPageData();
    }, [router.asPath.split('?')[0]])

    // Function to toggle between login and sign up forms
    const switchTab = () => {
        setIsSwitch(!isSwitch);
    }

    // Render the Account component
    return (
        <>
            {/* Display a welcome message with the user's name */}
            {/* <h1>Welcome, {accountPageData?.user?.name}!</h1> */}

            {/* Button to toggle between login and signup forms */}
            <button ref={buttonRef} onClick={switchTab}>
                {isSwitch ? "Log in to your account" : "Create an account"}
            </button>

            {/* Conditional rendering based on the switch state */}
            {isSwitch ? (
                <div>
                    {/* Render the login form here */}
                </div>
            ) : (
                <div>
                    {/* Render the sign up form here */}
                </div>
            )}
        </>
    )
}

// Export the Account component as the default export
export default Account

Hello @xbrandonpowell,

Yes, you don’t need to define it since it’s already defined config → shopify.ts file but the way you were passing the “account-page” string ( await shopifyConfig (‘account-page’)) to that function was incorrect, therefore, you will need to define a separate function that will fetch the account-page using fetch API and shopify config

if (!process.env.SHOPIFY_STORE_DOMAIN) {
  throw new Error('Missing required environment variable SHOPIFY_STORE_DOMAIN')
}
if (!process.env.SHOPIFY_STOREFRONT_API_TOKEN) {
  throw new Error(
    'Missing required environment variable SHOPIFY_STOREFRONT_API_TOKEN'
  )
}

export default {
  domain: process.env.SHOPIFY_STORE_DOMAIN,
  storefrontAccessToken: process.env.SHOPIFY_STOREFRONT_API_TOKEN,
}

This part is not needed, you can import it from config → shopify.ts

import shopifyConfig from '@config/shopify'

rename this function accountConfig or something and update below part

// Fetch account page data using the shopifyConfig function
const data = await accountConfig (‘account-page’);

So I have change to accountConfig but when uncommect the import to the shopify.ts file look like fully highlight like fade so this look shopifyConfig not been call within the file at all.

/** @jsxRuntime classic */
/** @jsx jsx */

import React, { FC, useState, useEffect, useRef } from 'react';
import { useRouter } from 'next/router'
import { jsx } from '@emotion/react'
import shopifyConfig from '@config/shopify'

interface ShopifyConfigResponse {
  domain: 'process.env.SHOPIFY_STORE_DOMAIN';
  storefrontAccessToken: 'process.env.SHOPIFY_STOREFRONT_API_TOKEN';
}

const accountConfig = async (configKey: string): Promise<ShopifyConfigResponse> => {
  // Implementation of fetching Shopify configuration data
  // This is just a placeholder, replace it with your actual implementation
  const response = await fetch(`/api/shopify/config/${configKey}`);
  const data = await response.json();
  return data;
};

// Define the Props interface for the Account component
interface Props {
    className?: string
    id?: string
}

// Define the Account component as a Functional Component (FC) with Props
const Account: FC<Props> = () => {
    // Get the router object from Next.js
    const router = useRouter()

    // State variables for managing the component's behavior
    const [isSwitch, setIsSwitch] = useState(false) // Toggle between login and sign up forms
    const buttonRef = useRef<HTMLDivElement>(null) // Reference to the button element
    const [accountPageData, setAccountPageData] = useState<ShopifyConfigResponse | null>(null);; // Store data related to the account page

    // Effect hook to fetch data when the route changes
    useEffect(() => {
        const fetchAccountPageData = async () => {
            // Fetch account page data using the shopifyConfig function
            const data = await accountConfig ('account-page');
            // Set the fetched data and update the switch state
            setAccountPageData(data);
            setIsSwitch(false);
        }
        // Trigger the fetch when the route changes (excluding query parameters)
        fetchAccountPageData();
    }, [router.asPath.split('?')[0]])

    // Function to toggle between login and sign up forms
    const switchTab = () => {
        setIsSwitch(!isSwitch);
    }

    // Render the Account component
    return (
        <>
            {/* Display a welcome message with the user's name */}
            {/* <h1>Welcome, {accountPageData?.user?.name}!</h1> */}

            {/* Button to toggle between login and sign up forms */}
            <button ref={buttonRef} onClick={switchTab}>
                {isSwitch ? "Log in to your account" : "Create an account"}
            </button>

            {/* Conditional rendering based on the switch state */}
            {isSwitch ? (
                <div>
                    {/* Render the login form here */}
                </div>
            ) : (
                <div>
                    {/* Render the sign up form here */}
                </div>
            )}
        </>
    )
}

// Export the Account component as the default export
export default Account

Replace ShopifyConfigResponse with shopifyConfig

1 Like