# DAO UI Tutorial p1

Somnia empowers developers to build applications for mass adoption. Smart Contracts deployed on the Somnia Blockchain will sometimes require building a User Interface. This guide will teach you how to build a user interface for a [DAO Smart Contract](https://docs.somnia.network/developer/building-dapps/example-applications/dao-smart-contract) using Next.js and React Context. It is divided into three parts. At the end of this guide, you’ll learn how to:

1. Initialize a Next.js project.
2. Set up a global state using the Context API ([**`useContext`**](https://react.dev/reference/react/useContext) hook).
3. Add a global NavBar in **`_app.js`** so it appears on every page.

You will have a basic skeleton of a DApp, ready for **READ/WRITE** operations and UI components —topics we’ll cover in the subsequent articles.

***

## Pre-requisites: <a href="#pre-requisites" id="pre-requisites"></a>

1. This guide is not an introduction to JavaScript Programming; you are expected to understand JavaScript.
2. To complete this guide, you will need MetaMask installed and the Somnia Network added to the list of Networks. If you have yet to install MetaMask, please follow this guide to [Connect Your Wallet](https://codex.somnia.network/get-started/connect-your-wallet).

## Create Your Next.js Project

To create a NextJS project, run the command:

```bash
npx create-next-app my-dapp-ui
```

Accept the prompts and change directory into the folder after the build is completed.

This gives you a minimal Next.js setup with a pages folder (holding your routes), a public folder (for static assets), and config files.

#### (Optional) Add Tailwind CSS

If you plan to style your app with Tailwind, install and configure it now:

```bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

Then edit your tailwind.config.js:

```javascript
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

Finally, include Tailwind in styles/globals.css:

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

***

## Setting Up a React Context for Global State

In many DApps, including this one, developers will manage **Wallet connection** and **State** globally so each page and component in the project can access it without repetitive code. This can be achieved by a [Context](https://react.dev/learn/passing-data-deeply-with-context) following React patterns.&#x20;

* Create a folder and name it **`contexts`** at the project root or inside **`pages`** directory.
* Inside it, create a file called **`walletcontext.js`** add the following code to the file:

<details>

<summary>walletcontext.js</summary>

```javascript
import { createContext, useContext, useState } from "react";

const WalletContext = createContext();

export function WalletProvider({ children }) {
  const [connected, setConnected] = useState(false);
  const [address, setAddress] = useState("");
  
  async function connectToMetaMask() {
    if (typeof window !== "undefined" && window.ethereum) {
      try {
        await window.ethereum.request({ method: "eth_requestAccounts" });
        // For simplicity, get the first address
        const [userAddress] = window.ethereum.selectedAddress
          ? [window.ethereum.selectedAddress]
          : [];
        setAddress(userAddress);
         setConnected(true);
      } catch (err) {
        console.error("User denied account access:", err);
      }
    } else {
      console.log("MetaMask is not installed!");
    }
  }

  function disconnectWallet() {
    setConnected(false);
    setAddress("");
  }

  // Return the context provider
  return (
<WalletContext.Provider
      value={{
        connected,
        address,
        connectToMetaMask,
        disconnectWallet,
      }}
    >
      {children}
    </WalletContext.Provider>
  );
}


export function useWallet() {
  return useContext(WalletContext);
}

```

</details>

We parse three class methods from React: **`createContext`**, **`useContext`**, an&#x64;**`useState`**

`createContext` is used to create a [context](https://react.dev/learn/passing-data-deeply-with-context) that components can provide or read. In this example, we assign `createContext` to the **`WalletContext`** variable and call the **`Provider`** method on each State and Function to make them available throughout the application.

**`useWallet()`** is a custom hook, so any page or component can do:

```javascript
const { connected, ... } = useWallet()
```

to access the global wallet state i.e. any of the **`Wallet.Provider`** methods

**`connectToMetaMask()`** triggers the MetaMask connection flow.

**`WalletProvider`** manages **State** and **Methods** in the application.

***

## Creating a Global NavBar in \_app.js

Next.js automatically uses **`pages/_app.js`** to initialize every page. We will wrap the entire app in the **`WalletProvider`** inside `_app.js` and inject a **`NavBar`** menu that appears site-wide in the application

#### Create the `_app.js`  and add the code:

```javascript
import "../styles/globals.css";
import { WalletProvider } from "../contexts/walletcontext";
import NavBar from "../components/navbar";

function MyApp({ Component, pageProps }) {
  return (
    <WalletProvider>
      <NavBar />
      <main className="pt-16">
        <Component {...pageProps} />
      </main>
    </WalletProvider>
  );
}

export default MyApp;
```

**`<WalletProvider>`** wraps the entire **`<Component />`** tree so that every page can share the same wallet state.

**`<NavBar />`** is placed above **`<main>`**, so it’s visible on all pages. We give **`<main>`** a pt-16 to avoid content hiding behind a fixed navbar.

## NavBar

Create a sub directory **components** and add a file called **`navbar.js`** Add the code:

```javascript
import { useWallet } from "../contexts/walletcontext";
import Link from "next/link";

export default function NavBar() {
  const { connected, address, disconnectWallet } = useWallet();


  return (
    <nav className="fixed w-full bg-white shadow z-50">
      <div className="mx-auto max-w-7xl px-4 flex h-16 items-center justify-between">
        <Link href="/">
          <h1 className="text-xl font-bold text-blue-600">MyDAO</h1>
        </Link>
<div>
          {connected ? (
            <div className="flex items-center space-x-4 text-blue-500">
              <span>{address.slice(0, 6)}...{address.slice(-4)}</span>
              <button onClick={disconnectWallet} className="px-4 py-2 bg-red-500 text-white rounded">
                Logout
              </button>
            </div>
          ) : (
            <span className="text-gray-500">Not connected</span>
          )}
        </div>
      </div>
    </nav>
  );
}
```

It uses **`useWallet()`** to read the global `connected` and `address`states, and the **`disconnectWallet`** function. The truncated `address` is displayed if a user is logged into the App or “Not connected” otherwise. A **Logout** button calls **`disconnectWallet()`** to reset the global state.

***

## Test Your Setup

Start the dev server:

```bash
npm run dev
```

Open **<http://localhost:3000>** in a Web Browser.\
\
You should see your NavBar at the top.

<figure><img src="https://2122549367-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkYErT9t3BJtpPfejLO6I%2Fuploads%2Fl9fqbfW5Kr8EGo0TI4H1%2FNot_Logged_In.png?alt=media&#x26;token=7ed9498d-59ea-404a-89d8-e2e196073877" alt=""><figcaption><p>Not Logged In</p></figcaption></figure>

<figure><img src="https://2122549367-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkYErT9t3BJtpPfejLO6I%2Fuploads%2FyctcgnYDLdzAshYqW54b%2FLogged_In.png?alt=media&#x26;token=6f8b2631-921e-444a-a11d-0e8c91dd42f1" alt=""><figcaption><p>Logged In</p></figcaption></figure>

Because we haven’t built any advanced pages yet, you will see a blank home page. The important part is that your **WalletContext** and global **NavBar** are in place and ready for the next steps.\ <br>

***

### 5. Next Steps

* Article 2 shows you how to implement READ/WRITE operations (e.g., deposit, create proposals, vote, etc.) across different Next.js pages—using the same WalletContext to handle contract calls.
* Article 3 will focus on UI components, like forms, buttons, and event handling, tying it all together into a polished user interface.

Congratulations! You have a clean foundation, a Next.js project configured with Tailwind, a global context to manage wallet states, and a NavBar appearing across all routes. This sets the stage for adding contract interactions and advanced UI flows in the subsequent articles. Happy building!

<br>
