Skip to content

Commit

Permalink
initial commit, page, routes and form lego setup
Browse files Browse the repository at this point in the history
  • Loading branch information
skuhlmann committed Sep 7, 2023
1 parent 366aa73 commit a6e21ac
Show file tree
Hide file tree
Showing 20 changed files with 481 additions and 854 deletions.
177 changes: 6 additions & 171 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,188 +1,23 @@
# DAO MiniApp Starter (vite)
# SiloHAUS RDF Summoner

Vite React Starter for a DAO app scoped to a single DAO.
Summon RDF DAOs.

## Development

### 1. Project Setup

#### NPX/degit

```bash
npx degit HausDAO/dao-app-starter-vite my-daohaus-app

cd my-daohaus-app

git init

yarn
```

#### SSH

```bash
git clone [email protected]:HausDAO/moloch-v3-vite-starter.git

git remote remove origin

cd dh-moloch-v3-vite-starter

yarn
```

#### HTTPS
### Clone and install

```bash
git clone https://github.com/HausDAO/dh-v3-vite-starter.git

git remote remove origin

cd dh-moloch-v3-vite-starter

yarn
yarn install
```

### 2. `.env` Setup
### `.env` Setup

```bash
cp .env.sample .env
```

```yaml
VITE_RIVET_KEY
```

Get a free Rivet key [here](https://rivet.cloud/)

```yaml
VITE_EXPLORER_KEY
```

Get an Etherscan API key [here](https://etherscan.io/apis)

```yaml
VITE_GRAPH_API_KEY_MAINNET
```

If developing for Mainnet or Gnosis Chain you can get an API key [here](https://thegraph.com/explorer/subgraph?id=GfHFdFmiSwW1PKtnDhhcxhArwtTjVuMnXxQ5XcETF1bP&view=Overview). Ignore this one if not worried about mainnet or gnosis chain yet.

```yaml
VITE_TARGET_KEY
```

This is the target address for the DAO you are developing the app for. You will get this value in the next step if you do not have an existing DAO.

### 3. Target DAO Set-up

[Summon](https://summon.daohaus.club) a DAO

#### Edit `src/targetDao.ts`

Add your DAO's data to the property and values of the object

#### Edit `.env`

Add the DAO address in the `VITE_TARGET_KEY` variable

- You can add multiple DAOs as new objects in `targetDao.ts` and toggle with this `env` variable
- You can add other variables to `targetDao.ts` as needed

### 4. Run the Development Server
### Run the Development Server

```bash
yarn dev
```

## Reference

### `main.tsx`

- Sets up the `react-query` provider `@daohaus/moloch-v3-hooks` will use
- Sets up `DHConnectProvider` - that handles the Wallet Connect functionality
- Sets up `HausThemeProvider` - that provides the styling theme to the app
- Adds the router to the app

### `HomeContainer.tsx`

- Parent component wrapping all routes/pages
- Sets up `DHLayout` which adds the connect button and navigation to the app
- You can update the navigation in `navLinks`
- Sets up `TXBuilder` which enables easy transaction creation

### `FormTest.tsx`

- Example of how to add `FormBuilder` to the app
- See the legos it is using at `legos/forms.ts`, `legos/fields.ts`, and `legos/tx.ts`
- These are recipes for creating forms and contract function interactions

### ToDo

- Ad routes/pages for dao overview, vaults, settings
- proposals, members and profile coming soon
- show hook data fetch
- show macro ui addition
- `moloch-v3-fields` package
- coming soon

### Adding UI Components

- [Storybook](https://storybook.js.org/)

### Methods for Accessing `daoid` and `daochain`

These values are used in most hooks and components and you have some options:

Get them from `targetDao.ts`

```tsx
const daoChain = TARGET_DAO[import.meta.env.VITE_TARGET_KEY].CHAIN_ID;
const daoId = TARGET_DAO[import.meta.env.VITE_TARGET_KEY].ADDRESS;
```

or load them into a context from the `@daohaus/moloch-v3-hooks` library and then there is a hook you can use.

Wrap your tree in this context:

```tsx
import { CurrentDaoProvider } from "@daohaus/moloch-v3-hooks";

...

<CurrentDaoProvider
targetDao={{
daoChain: TARGET_DAO[import.meta.env.VITE_TARGET_KEY].CHAIN_ID,
daoId: TARGET_DAO[import.meta.env.VITE_TARGET_KEY].ADDRESS,
}}
>
{children}
</CurrentDaoProvider>;
```

Then access this hook:

```tsx
import { useCurrentDao } from "@daohaus/moloch-v3-hooks";
...

const { daoChain, daoId } = useCurrentDao();
```

- Future: `urlParams` in a multi DAO app

### Adding Custom Fields

tbd

### Editing the Theme

tbd

### Router Example for Multi DAO App

tbd

## Resources

- [DAO Toolbox](https://toolbox.daohaus.fun/) docs
- HausDAO monorepo [libs](https://github.com/HausDAO/monorepo/tree/develop/libs)
- monorepo admin/admin-new
34 changes: 4 additions & 30 deletions src/Routes.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,15 @@
import { Routes as Router, Route } from "react-router-dom";
import { FormTest } from "./pages/FormTest";
import { Home } from "./pages/Home";
import { LayoutContainer } from "./components/LayoutContainer";
import Dao from "./pages/Dao";
import { Safes } from "./pages/Safes";
import { Settings } from "./pages/Settings";
import { Proposals } from "./pages/Proposals";
import { Proposal } from "./pages/Proposal";
import { Members } from "./pages/Members";
import { Member } from "./pages/Member";
import { TARGET_DAO } from "./targetDao";
import RageQuit from "./pages/RageQuit";

const routePath = `molochv3/${
TARGET_DAO[import.meta.env.VITE_TARGET_KEY].CHAIN_ID
}/${TARGET_DAO[import.meta.env.VITE_TARGET_KEY].ADDRESS}`;
import Home from "./pages/Home";
import Success from "./pages/Success";
import { LayoutContainer } from "./components/LayoutContainer";

export const Routes = () => {
return (
<Router>
<Route path="/" element={<LayoutContainer />}>
<Route index element={<Home />} />
<Route path={`${routePath}/formtest`} element={<FormTest />} />
<Route path={`${routePath}/dao`} element={<Dao />} />
<Route path={`${routePath}/safes`} element={<Safes />} />
<Route path={`${routePath}/settings`} element={<Settings />} />
<Route path={`${routePath}/proposals/`} element={<Proposals />} />
<Route
path={`${routePath}/proposal/:proposalId`}
element={<Proposal />}
/>
<Route path={`${routePath}/members/`} element={<Members />} />
<Route
path={`${routePath}/member/:memberAddress`}
element={<Member />}
/>
<Route path={`${routePath}/members/ragequit`} element={<RageQuit />} />
<Route path={`success/:daoId`} element={<Success />} />
</Route>
</Router>
);
Expand Down
34 changes: 34 additions & 0 deletions src/components/Brand.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { styled } from "styled-components";
import { H5 } from "@daohaus/ui";
import { Link } from "react-router-dom";

const Container = styled.div`
display: flex;
flex-direction: row;
gap: 1.5rem;
@media (max-width: 800px) {
gap: 1rem;
}
`;

const BrandLink = styled(Link)`
display: flex;
align-items: center;
gap: 1.5rem;
color: unset;
text-decoration: unset;
&:hover {
color: unset;
}
`;

export const Brand = () => {
return (
<Container>
<BrandLink to="/">
<H5>SILO RDF SUMMONER</H5>
</BrandLink>
</Container>
);
};
83 changes: 36 additions & 47 deletions src/components/LayoutContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,46 @@
import { DHLayout, useDHConnect } from "@daohaus/connect";
import { Outlet } from "react-router-dom";
import { styled } from "styled-components";

import { DaoHausNav, useDHConnect } from "@daohaus/connect";
import { TXBuilder } from "@daohaus/tx-builder";
import { H4 } from "@daohaus/ui";
import { Outlet, useLocation, useParams } from "react-router-dom";
import { TARGET_DAO } from "../targetDao";
import { CurrentDaoProvider, useDaoData } from "@daohaus/moloch-v3-hooks";
import { Footer, MainLayout, OuterLayout, widthQuery } from "@daohaus/ui";
import { Brand } from "./Brand";

const routePath = `molochv3/${
TARGET_DAO[import.meta.env.VITE_TARGET_KEY].CHAIN_ID
}/${TARGET_DAO[import.meta.env.VITE_TARGET_KEY].ADDRESS}`;
const Header = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
padding: 2.6rem 3rem;
width: 100%;
@media ${widthQuery.sm} {
padding: 2rem;
}
.left-nav {
@media ${widthQuery.sm} {
width: 100%;
}
}
`;

export const LayoutContainer = () => {
const location = useLocation();
const { proposalId, memberAddress } = useParams<{
proposalId: string;
memberAddress: string;
}>();
const { publicClient, address } = useDHConnect();
const { dao } = useDaoData({
daoId: TARGET_DAO[import.meta.env.VITE_TARGET_KEY].ADDRESS,
daoChain: TARGET_DAO[import.meta.env.VITE_TARGET_KEY].CHAIN_ID,
});
const { publicClient, address, chainId } = useDHConnect();

return (
<DHLayout
pathname={location.pathname}
navLinks={[
{ label: "Home", href: `/` },
{ label: "DAO Overview", href: `${routePath}/dao` },
{ label: "Safes", href: `${routePath}/safes` },
{ label: "Proposals", href: `${routePath}/proposals` },
{ label: "Members", href: `${routePath}/members` },
{ label: "Settings", href: `${routePath}/settings` },
]}
leftNav={<H4>{dao?.name}</H4>}
<TXBuilder
publicClient={publicClient}
chainId={chainId}
appState={{ memberAddress: address }}
>
<CurrentDaoProvider
targetDao={{
daoChain: TARGET_DAO[import.meta.env.VITE_TARGET_KEY].CHAIN_ID,
daoId: TARGET_DAO[import.meta.env.VITE_TARGET_KEY].ADDRESS,
proposalId,
memberAddress,
}}
>
<TXBuilder
publicClient={publicClient}
chainId={TARGET_DAO[import.meta.env.VITE_TARGET_KEY].CHAIN_ID}
daoId={TARGET_DAO[import.meta.env.VITE_TARGET_KEY].ADDRESS}
safeId={TARGET_DAO[import.meta.env.VITE_TARGET_KEY].SAFE_ADDRESS}
appState={{ dao, memberAddress: address }}
>
<OuterLayout>
<Header>
<div className="left-nav">{<Brand />}</div>
<DaoHausNav />
</Header>
<MainLayout>
<Outlet />
</TXBuilder>
</CurrentDaoProvider>
</DHLayout>
</MainLayout>
<Footer />
</OuterLayout>
</TXBuilder>
);
};
Loading

0 comments on commit a6e21ac

Please sign in to comment.