Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: UI to mint tickets #18

Merged
merged 71 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
bb3bf3c
chore: run `yarn create vite` to initialize the UI
LuqiPan Feb 21, 2024
04996c8
chore: add relevant dependencies and run `yarn install`
LuqiPan Feb 22, 2024
156d456
feat: add SES lockdown
LuqiPan Feb 22, 2024
abf30d9
feat: add relevant types, hooks, and store
LuqiPan Feb 22, 2024
353c23d
feat: add contract provider
LuqiPan Feb 22, 2024
f06fbd2
feat: add component for Mint and Inventory
LuqiPan Feb 22, 2024
e493bd1
feat: organize all components in App
LuqiPan Feb 22, 2024
4a2decf
fix: replace occurrences of items with tickets in interchain-ui code
LuqiPan Feb 22, 2024
3adf925
Merge branch '939-mint-tickets' into 977-mint-tickets-ui
LuqiPan Feb 22, 2024
09beec3
chore: add a yarn script for starting interchain-ui
LuqiPan Feb 22, 2024
5ca8da2
fix: use correct contract name to find the contract instance
LuqiPan Feb 22, 2024
525e02a
chore: install Tailwind CSS
LuqiPan Feb 22, 2024
f42417a
chore: configure template paths for Tailwind CSS
LuqiPan Feb 22, 2024
f365767
fix: let vite know about the type definition for stringifyAmountValue
LuqiPan Feb 22, 2024
77ba37f
chore: remove all existing css and add Tailwind directives
LuqiPan Feb 22, 2024
1c44c01
ui: use tailwind to arrange the flex box for the app
LuqiPan Feb 22, 2024
cd3d6d6
ui: remove old css classes and use tailwind to do styling instead
LuqiPan Feb 22, 2024
a1079f6
ui: make the vertical divider show up
LuqiPan Feb 23, 2024
53403b4
chore: upgrade ses to 1.3.0
LuqiPan Feb 23, 2024
6bdc476
feat: wire up Mint component to send actual offers to contract
LuqiPan Feb 23, 2024
eb288d8
fix: update Inventory component to use the correct purse
LuqiPan Feb 23, 2024
15d6ff6
feat: add proper images for different kind of seats
LuqiPan Feb 23, 2024
5b11aae
ui: remove some redundant styling
LuqiPan Feb 23, 2024
79ee77c
ui: add a connect wallet button at top right corner
LuqiPan Feb 23, 2024
ac40c18
ui: add app name on top left
LuqiPan Feb 23, 2024
d8417a8
ui: update index.html with proper favicon and title
LuqiPan Feb 23, 2024
da229f4
chore: install daisyui
LuqiPan Feb 27, 2024
5ee43ad
chore: update tailwind config to use daisyui
LuqiPan Feb 27, 2024
80be054
ui: use daisyui to style buttons
LuqiPan Feb 27, 2024
829b634
ui: use daisyui to style the inventory card
LuqiPan Feb 27, 2024
4431697
ui: style a navbar with daisyui
LuqiPan Feb 27, 2024
b2c4ab4
ui: use daisyui-divider-horizontal
LuqiPan Feb 27, 2024
06b95da
ui: add agoric logo on the navbar
LuqiPan Feb 27, 2024
6441fd0
ui: add a daisyui tab without hooking it up to contents below
LuqiPan Feb 27, 2024
e4a1cf5
chore: add react-daisyui
LuqiPan Feb 27, 2024
1d44dae
chore: configure daisyui-react
LuqiPan Feb 27, 2024
2ce38a0
ui: start styling a mint card through daisyui
LuqiPan Feb 27, 2024
4a9a8e5
ui: styling the mint card
LuqiPan Feb 27, 2024
c982cdd
chore: remove unused import
LuqiPan Feb 27, 2024
5bfb7d6
chore: remove @interchain-ui/react as this package is no longer in use
LuqiPan Feb 27, 2024
45b3b23
ui: add styling so items are aligned on vertical center
LuqiPan Feb 28, 2024
c024189
ui: use self-center to align items individually
LuqiPan Feb 28, 2024
e1ec98d
ui: get radio tabs working
LuqiPan Feb 28, 2024
7da79ce
ui: flex card action vertically instead
LuqiPan Feb 28, 2024
38a2f55
ui: DRY out tab wrapper into TabWrapper component
LuqiPan Feb 28, 2024
f18242b
refactor: re-organize all components into a better hierarchy
LuqiPan Feb 28, 2024
1a0e022
chore: remove redundant div
LuqiPan Feb 28, 2024
c2be33f
chore: run `yarn add '@agoric/react-components'`
LuqiPan Feb 29, 2024
483e76f
chore: fix small formatting issue
LuqiPan Mar 1, 2024
db720dc
ui: implement notifications as toasts
LuqiPan Mar 5, 2024
6e82577
Merge branch 'main' into 977-mint-tickets-ui
LuqiPan Mar 6, 2024
e5d2c44
Merge branch 'main' into 977-mint-tickets-ui
LuqiPan Mar 6, 2024
d480989
chore: bump web-components to 0.15.1-dev-09ca26c.0
LuqiPan Mar 6, 2024
a6bab79
chore: remove unused declares in vite-env.d.ts
LuqiPan Mar 6, 2024
291515f
chore: update code to use stringifyAmountValue from @agoric/web-compo…
LuqiPan Mar 6, 2024
6b893f1
chore: update @agoric/react-components to the latest version
LuqiPan Mar 7, 2024
6735236
chore: remove debugging logging statement
LuqiPan Mar 7, 2024
01a6ec3
chore: update @agoric/react-component to latest
LuqiPan Mar 13, 2024
e988954
ui: add network dropdown component
LuqiPan Mar 13, 2024
1150103
chore: remove mainnet from network configs
LuqiPan Mar 13, 2024
3bd9b05
chore: replace ui folder with interchain-ui folder
LuqiPan Apr 2, 2024
b6e8e34
chore: update package.json and ui/package.json
LuqiPan Apr 2, 2024
1789cef
chore: add a test script for ui workspace
LuqiPan Apr 2, 2024
1464360
Merge branch 'main' into 977-mint-tickets-ui
LuqiPan Apr 2, 2024
95ca6af
chore: add and update some yarn scripts
LuqiPan Apr 2, 2024
b52baff
chore: run `yarn install`
LuqiPan Apr 4, 2024
2691ff3
chore: remove `print-key` yarn script
LuqiPan Apr 4, 2024
6363c67
chore: remove `print-key` make target
LuqiPan Apr 4, 2024
5066ea6
chore: remove invoking print-key in start
LuqiPan Apr 4, 2024
2bb65f8
chore: add .node-version and .nvmrc file
LuqiPan Apr 5, 2024
e35fe0f
Merge branch 'luqi-various-fixes' into 977-mint-tickets-ui
LuqiPan Apr 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions interchain-ui/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
}
24 changes: 24 additions & 0 deletions interchain-ui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
30 changes: 30 additions & 0 deletions interchain-ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:

- Configure the top-level `parserOptions` property like this:

```js
export default {
// other rules...
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: ['./tsconfig.json', './tsconfig.node.json'],
tsconfigRootDir: __dirname,
},
}
```

- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list
13 changes: 13 additions & 0 deletions interchain-ui/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/agoric.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>dApp Agoric Basics</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
51 changes: 51 additions & 0 deletions interchain-ui/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "interchain-ui",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@agoric/react-components": "^0.1.1-dev-8fc28e8.0",
"@agoric/ui-components": "^0.3.9-u13.0",
"@agoric/web-components": "^0.15.1-dev-09ca26c.0",
"buffer": "^6.0.3",
"chain-registry": "^1.28.1",
"cosmos-kit": "^2.9.0",
"daisyui": "^4.7.2",
"react": "^18.2.0",
"react-daisyui": "^5.0.0",
"react-dom": "^18.2.0",
"ses": "^1.2.0"
},
"devDependencies": {
"@types/react": "^18.2.56",
"@types/react-dom": "^18.2.19",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.17",
"eslint": "^8.56.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"postcss": "^8.4.35",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.11",
"tailwindcss": "^3.4.1",
"typescript": "^5.2.2",
"vite": "^5.1.4"
},
"prettier": {
"trailingComma": "all",
"arrowParens": "avoid",
"singleQuote": true,
"tabWidth": 2,
"plugins": [
"prettier-plugin-tailwindcss"
]
}
}
6 changes: 6 additions & 0 deletions interchain-ui/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
10 changes: 10 additions & 0 deletions interchain-ui/public/agoric.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions interchain-ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { ContractProvider } from './providers/Contract';
import { AgoricProvider } from '@agoric/react-components';
import { Navbar } from './components/Navbar';
import { Tabs } from './components/Tabs';
import { wallets } from 'cosmos-kit';
import '@agoric/react-components/dist/style.css';

function App() {
return (
<AgoricProvider
wallets={wallets.extension}
defaultNetworkConfig={{
testChain: {
chainId: 'agoriclocal',
chainName: 'agoric-local',
},
apis: {
rest: ['http://localhost:1317'],
rpc: ['http://localhost:26657'],
},
}}
>
<ContractProvider>
<Navbar />
<Tabs />
</ContractProvider>
</AgoricProvider>
);
}

export default App;
Binary file added interchain-ui/src/assets/IST.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added interchain-ui/src/assets/frontRow.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added interchain-ui/src/assets/lastRow.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added interchain-ui/src/assets/middleRow.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions interchain-ui/src/components/Inventory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { AmountMath } from '@agoric/ertp';
import { ConnectWalletButton, useAgoric } from '@agoric/react-components';
import { stringifyAmountValue } from '@agoric/web-components';
import { usePurse } from '../hooks/usePurse';
import type { CopyBag } from '../types';

const Inventory = () => {
const istPurse = usePurse('IST');
const ticketsPurse = usePurse('Ticket');
const { walletConnection } = useAgoric();

return (
<div className="daisyui-card w-96 bg-base-100 shadow-xl">
<div className="daisyui-card-body items-center text-center">
<h2 className="daisyui-card-title">My Wallet</h2>
<div className="daisyui-card-actions">
<div>
<ConnectWalletButton className="daisyui-btn daisyui-btn-outline daisyui-btn-primary" />
{walletConnection && (
<div>
<div>
<b>IST: </b>
{istPurse ? (
stringifyAmountValue(
AmountMath.make(
istPurse?.currentAmount.brand,
istPurse?.currentAmount.value,
),
istPurse.displayInfo.assetKind,
istPurse.displayInfo.decimalPlaces,
)
) : (
<i>Fetching balance...</i>
)}
</div>
<div>
<b>Tickets: </b>
{ticketsPurse ? (
<ul>
{(
ticketsPurse.currentAmount.value as CopyBag
).payload.map(([name, number]) => (
<li key={name}>
{String(number)} {name}
</li>
))}
</ul>
) : (
'None'
)}
</div>
</div>
)}
</div>
</div>
</div>
</div>
);
};

export { Inventory };
50 changes: 50 additions & 0 deletions interchain-ui/src/components/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { ConnectWalletButton } from '@agoric/react-components';
import { NetworkDropdown } from '@agoric/react-components';
import { ThemeProvider, useTheme } from '@interchain-ui/react';

const localnet = {
testChain: {
chainId: 'agoriclocal',
chainName: 'agoric-local',
},
apis: {
rest: ['http://localhost:1317'],
rpc: ['http://localhost:26657'],
iconUrl: '/agoriclocal.svg', // Optional icon for dropdown display
},
};

const Navbar = () => {
const { themeClass } = useTheme();

return (
<div className="daisyui-navbar bg-neutral text-neutral-content">
{/* Agoric logo */}
<div className="flex-none">
<button className="daisyui-btn daisyui-btn-square daisyui-btn-ghost">
<img src="/agoric.svg" />
</button>
</div>
{/* dApp title */}
<div className="flex-1">
<button className="daisyui-btn daisyui-btn-ghost text-xl">
dApp Agoric Basics
</button>
</div>
{/* network selector */}
<ThemeProvider>
<div className={themeClass}>
<div>
<NetworkDropdown networkConfigs={[localnet]} />
</div>
</div>
</ThemeProvider>
{/* connect wallet button */}
<div className="flex-none">
<ConnectWalletButton className="daisyui-btn daisyui-btn-outline daisyui-btn-secondary" />
</div>
</div>
);
};

export { Navbar };
52 changes: 52 additions & 0 deletions interchain-ui/src/components/Notifications.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Toast, Alert, Button } from 'react-daisyui';
import { DynamicToastChild } from './Tabs';
import { Dispatch, SetStateAction } from 'react';

const daisyUiAlertClass = (status: string) => {
switch (status) {
case 'info':
return 'daisyui-alert-info';
case 'success':
return 'daisyui-alert-success';
case 'warning':
return 'daisyui-alert-warning';
case 'error':
return 'daisyui-alert-error';
default:
return '';
}
};

const Notifications = (props: {
notifications: DynamicToastChild[];
setNotifications: Dispatch<SetStateAction<DynamicToastChild[]>>;
}) => {
const handleRemoveToast = (index: number) => {
props.setNotifications(notifications =>
notifications.filter((_, i) => i !== index),
);
};

return (
<div>
<Toast className="daisyui-toast daisyui-toast-end daisyui-toast-top">
{props.notifications.map((alert, index) => (
<Alert
className={'daisyui-alert ' + daisyUiAlertClass(alert.status)}
key={index}
status={alert.status}
>
<div className="w-full flex-row justify-between gap-2">
<h3>{alert.text}</h3>
</div>
<Button color="ghost" onClick={() => handleRemoveToast(index)}>
X
</Button>
</Alert>
))}
</Toast>
</div>
);
};

export { Notifications };
25 changes: 25 additions & 0 deletions interchain-ui/src/components/TabWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ReactNode } from 'react';

const TabWrapper = (props: { tab: string; activeTab: string, handleTabClick:(tab: string)=>void, children: ReactNode }) => {
return (
<>
<input
type="radio"
name={props.tab}
role="tab"
className="daisyui-tab"
aria-label={props.tab}
checked={(props.activeTab === props.tab)}
onClick={()=>{props.handleTabClick(props.tab)}}
/>
<div
role="tabpanel"
className="daisyui-tab-content rounded-box border-base-300 bg-base-100 p-6"
>
{props.children}
</div>
</>
);
};

export { TabWrapper };
Loading
Loading