# Allo DX
> Documentation-first approach to explore DX (developer experience).
>
> Ideas and reasoning from Allo Sketchbook:
> https://hackmd.io/jR492-g5QBKrgQXV00R4zQ?edit
### Getting Started
#### Installation
```shell
npx create-allo-app@latest
```
#### Create a new Strategy contract
Simple contract that transfer tokens to a collection recipients
```solidity
import { Strategy } from "@allo-team/contracts"
contract MinimalStrategy is Strategy {
function init(StrategyConfig config, bytes data) {
__Strategy_init(config, data);
}
function distribute(address[] recipients[], uint256[] amounts[]) external onlyRoundAdmin {
Utils.iteratePayouts(recipients, amounts, this.payout)
}
function payout(address recipient, uint256 amount) {
Tokens.transfer(recipient, amount);
emit Distribute(recipient, amount);
}
```
#### Deploy contract
```ts
await deploy("MinimalStrategy", [{
name: "MinimalStrategy",
// pointer to json with title, description, etc
metadata: "https://..."
admins: ["0x...456"]
}])
```
```sh
# Deployed strategy at address: 0x...123
```
### Configuring ApiProvider
ApiProvider is responsible for data fetching and contract interactions.
```jsx
// app/layout.tsx
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
<ApiProvider>
<main className="max-w-screen-lg mx-auto py-16">{children}</main>
</ApiProvider>
</body>
</html>
);
}
```
### Creating a page with form to create the round
To use our Strategy we need to create a round.
```jsx
// app/rounds/create/page.tsx
import { AdminCreateRound } from "@allo-team/kit";
export default function CreateRoundPage() {
return (
<AdminCreateRound
/*
AdminCreateRound is a component for admins to create new rounds.
A form will be rendered with a dropdown of the contracts and
fields for round configuration
Strategy addresses are passed as a prop and its name and metadata
fetched from the contract.
*/
strategies={["0x...123"]} onCreated={round =>
// Redirect to discover rounds page where we can see the newly created round
redirect(`/rounds/${round.id}`);
}
/>
)
}
```
### Discover Rounds page
```jsx
// app/rounds/discover/page.tsx
import Link from "next/link";
import { DiscoverRounds } from "@allo-team/kit";
export default function DiscoverRounds() {
return (
<DiscoverRounds
/*
DiscoverRounds is a pre-made component that does most of the heavy lifting
in fething and displaying rounds.
It fetches the rounds based on a provided query (with sane defaults) and
renders it (as a grid by default but easy to customize with own components).
*/
query={{
/*
The query prop enables a powerful way to fetch data from the indexer.
For example:
- only rounds with these strategies (deployed contract address)
- order by when they were created, newest first
- with skip and take we can paginate the results and decide how many to show
*/
orderBy: { createdAt: "desc" },
where: {
strategyAddress: { in: ["0x...123"] }
},
skip: 0,
take: 12,
}}
/*
The renderItem function lets us change what component is rendered.
For example:
- Wrap the default RoundItem component in a link
*/
renderItem={(round, Component) => (
<Link href={`/rounds/${round.id}`} key={round.id}>
<Component {...round} />
</Link>
)}
/*
Columns let us choose how to render the rounds.
For example:
- 1 column on phones
- 2 columns on small to medium
- 3 columns on medium to large
- 4 columns on large and above
We could also set it to [1] to render as list on all screens
*/
columns={[1, 2, 3, 4]}
/>
);
}
```