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

POAP Dashboard App (Milestones 1-4) #2

Merged
merged 135 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from 133 commits
Commits
Show all changes
135 commits
Select commit Hold shift + click to select a range
1a69749
import project
rikublock May 25, 2023
ab33866
add setup steps to readme
rikublock Jun 12, 2023
e18c927
add event overview, event details page
rikublock Jun 16, 2023
f1a6db6
add webpack
rikublock Jun 16, 2023
25a9eef
fix dev server routing
rikublock Jun 19, 2023
2b1e71e
add wallet providers
rikublock Jun 20, 2023
32ba19c
implement event sign up
rikublock Jun 20, 2023
6485cb0
remove old routes
rikublock Jun 20, 2023
5f48257
add profile dialog
rikublock Jun 21, 2023
816e2bf
disable close button while loading
rikublock Jun 21, 2023
9397781
improve profile dialog
rikublock Jun 21, 2023
d8a891e
tweak join dialog
rikublock Jun 22, 2023
a4f7a8f
add prettier config
rikublock Jun 22, 2023
8cd47fb
rework mint dialog
rikublock Jun 21, 2023
211bc94
mint dialog clean up
rikublock Jun 25, 2023
b2156cf
add connectivity status
rikublock Jun 25, 2023
03dabab
fix dev server config
rikublock Jun 26, 2023
d4c47e5
cumulative update
rikublock Jun 26, 2023
e2b153c
update gem provider
rikublock Jun 28, 2023
3936b3a
add authentication
rikublock Jul 1, 2023
d7fdcea
rework EventTable
rikublock Jul 1, 2023
1e831af
add updated API endpoints
rikublock Jul 2, 2023
a7fbb5f
add disabled to mint dialog checkbox
rikublock Jul 3, 2023
d41028b
add content wrapper
rikublock Jul 3, 2023
cf04923
prepare for api 2.0
rikublock Jul 3, 2023
924917f
update readme for API 2.0
rikublock Jul 4, 2023
623684a
limit add participants to at most 20 entries
rikublock Jul 4, 2023
b7eace9
add permissions state to auth context
rikublock Jul 4, 2023
a0c6d80
check permissions on pages
rikublock Jul 4, 2023
a86f0f6
make network status indicator non clickable
rikublock Jul 5, 2023
db66142
clean up event info page
rikublock Jul 5, 2023
b7cff65
add link to event info
rikublock Jul 5, 2023
ba500d7
snackbar tweaks
rikublock Jul 7, 2023
140f688
implement join api changes
rikublock Jul 11, 2023
e190ee6
update types
rikublock Jul 11, 2023
8871464
add stack for secondary button spacing
rikublock Jul 12, 2023
3eb7b0a
add get slots api
rikublock Jul 12, 2023
ca3a283
display available slots
rikublock Jul 12, 2023
4ae0b21
add event status to data table
rikublock Jul 12, 2023
df08972
fix offer index typing
rikublock Jul 12, 2023
f683a2e
style table depending on event expiration
rikublock Jul 12, 2023
871dfc2
add user wallet address auto complete options
rikublock Jul 13, 2023
3fd6d07
add debug page
rikublock Jul 20, 2023
0815276
clean up dialog set data
rikublock Jul 20, 2023
a223760
make loader text customizable
rikublock Jul 23, 2023
5f298e4
add get event link api
rikublock Jul 23, 2023
0dad78d
add create link dialog
rikublock Jul 23, 2023
d58e075
set default event creation type to public
rikublock Jul 23, 2023
2102809
fix comment typo
rikublock Jul 23, 2023
aefbacd
add admin page template
rikublock Aug 28, 2023
ccdbec7
add authorized minter api
rikublock Aug 28, 2023
5e8ccd8
add new admin routes
rikublock Aug 28, 2023
a6d31c7
rework providers to support new event minting flows
rikublock Aug 29, 2023
a06f928
add admin stats page template
rikublock Aug 29, 2023
51e6bfb
[tmp] claim workflow
rikublock Sep 4, 2023
d1d0673
[tmp] claim workflow 2
rikublock Sep 4, 2023
4c742b7
rework /events API
rikublock Sep 4, 2023
2a64ab4
add admin event list
rikublock Sep 4, 2023
82baea7
update API
rikublock Sep 4, 2023
4d92566
update /users API
rikublock Sep 4, 2023
27615f6
update admin users page
rikublock Sep 4, 2023
05ff5e6
rename mint -> create dialog
rikublock Sep 5, 2023
305a102
update admin pages
rikublock Sep 5, 2023
eb3b51f
backup new create dialog
rikublock Sep 7, 2023
f573c91
fix provider
rikublock Sep 7, 2023
f3e1ad7
update types
rikublock Sep 7, 2023
8d04ce2
add login flow switch
rikublock Sep 7, 2023
64e01dd
remove user based event slots
rikublock Sep 7, 2023
6535929
add eventId to create dialog state
rikublock Sep 7, 2023
3a0cbb4
add basic event card template
rikublock Sep 7, 2023
a20f5d5
add payment API
rikublock Sep 8, 2023
37ef584
add event cancel API
rikublock Sep 14, 2023
08f8fe9
add info box
rikublock Sep 14, 2023
92bd051
update connector to return txhash
rikublock Sep 14, 2023
d1d633d
basic working create flow
rikublock Sep 14, 2023
1908855
add cancel dialog
rikublock Sep 15, 2023
3ad71a8
complete create dialog
rikublock Sep 17, 2023
c77fa83
rework link dialog to re-use step
rikublock Sep 18, 2023
5532213
update event card
rikublock Sep 18, 2023
f9bfc7a
disable debug mode
rikublock Sep 18, 2023
9555b98
[wip] rework claim page
rikublock Sep 19, 2023
acd1a84
update layouts
rikublock Sep 19, 2023
f8928d9
add return_url if on mobile
rikublock Sep 19, 2023
9ccb181
rename menu entry to dashboard
rikublock Sep 19, 2023
8c7ca1c
change to local storage for xumm sdk
rikublock Sep 19, 2023
6ddd9f0
working claim setup
rikublock Sep 19, 2023
fc5ee80
add status, deposit amount row to event table
rikublock Sep 19, 2023
fa4ef70
remove attendee page
rikublock Sep 25, 2023
490968b
simplify content wrapper
rikublock Sep 25, 2023
dd2d5db
rework event info page
rikublock Sep 25, 2023
db91340
fix tooltip
rikublock Sep 25, 2023
85cca27
rework welcome page
rikublock Sep 25, 2023
99337a5
improve claim setup
rikublock Sep 25, 2023
129b3e8
remove obsolete logging
rikublock Sep 25, 2023
95fbec3
redirect when successfully connecting a wallet
rikublock Oct 2, 2023
2b7c4e6
capitalize readme bullets
rikublock Oct 2, 2023
ad825fb
prompt user to look at their wallet
rikublock Oct 2, 2023
9e28efc
display message when there are no events
rikublock Oct 2, 2023
86e2bdf
add debug clear storage
rikublock Oct 2, 2023
a4a50e2
rework home page
rikublock Oct 2, 2023
36f6863
add back button component
rikublock Oct 2, 2023
d0fe490
add offset prop
rikublock Oct 2, 2023
8998495
disable obsolete actions
rikublock Oct 2, 2023
01dca31
rework admin pages
rikublock Oct 2, 2023
d4249dd
add debug button to revoke authorized minter
rikublock Oct 3, 2023
6459cd1
add footer
rikublock Oct 2, 2023
316cd0a
add warning for low vault account balance
rikublock Oct 5, 2023
14dd950
make image optional during event creation
rikublock Oct 5, 2023
6499100
rename xumm -> xaman
rikublock Oct 7, 2023
a752c52
minor UI tweaks
rikublock Oct 7, 2023
544b04d
display deposit amount on event cards
rikublock Oct 9, 2023
f20f429
rework event info page
rikublock Oct 9, 2023
21bd3df
fix close dialog after disconnecting wallet
rikublock Oct 18, 2023
91b57be
add event share and cancel button to event info page
rikublock Oct 18, 2023
adc605c
adjust axios timeout for event API
rikublock Oct 24, 2023
6e6d271
show available event slots to any user
rikublock Oct 24, 2023
64df3ed
move content box component
rikublock Oct 26, 2023
05370c6
display NFT id on claim page
rikublock Oct 26, 2023
b85e91e
add event info page for mobile
rikublock Oct 24, 2023
98cef1e
enable filter menu in data tables
rikublock Oct 27, 2023
ce21537
list event owner address in admin event overview
rikublock Oct 27, 2023
2b74171
redirect after login depending on permissions
rikublock Oct 27, 2023
ceb6b64
require event end date to be in the future
rikublock Oct 28, 2023
dda317d
adjust app version
rikublock Nov 9, 2023
3c3f115
display wallet address after NFT claim
rikublock Nov 9, 2023
2b7ee01
add NFT ownership verification API
rikublock Nov 9, 2023
3c0259a
add NFT ownership verification page
rikublock Nov 9, 2023
9a291a2
clean up comments
rikublock Nov 9, 2023
f1b11e1
add content box labels
rikublock Nov 21, 2023
22aa432
only redirect during regular login
rikublock Nov 21, 2023
1311bf8
lazy mount add dialog
rikublock Nov 21, 2023
555fac4
add verify nft icon to event page
rikublock Nov 21, 2023
b212caa
add verify ownership note
rikublock Nov 22, 2023
8ba6a44
restore lost license file
rikublock Dec 2, 2023
d0a03ca
code clean up
rikublock Dec 2, 2023
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
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
REACT_APP_URL_POAP_API="http://localhost:4000/"
REACT_APP_KEY_XUMM_API=""
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
tabWidth: 2
semi: true
singleQuote: false
printWidth: 80
21 changes: 0 additions & 21 deletions LICENSE

This file was deleted.

53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,51 @@
# POAP-APP
The web app for Proof of Attendance Protocol
# POAP APP

The web app for Proof of Attendance Protocol

## Requirements
- Node.js `v18.16.0+`
- Yarn `v1.22.19+`
- Running POAP API 2.0 server (backend), for details see [here](https://github.com/rikublock/POAP-API2)

## Getting Started
- Install dependencies with `yarn install`
- Rename `.env.example` to `.env` (change values as needed)
- `REACT_APP_URL_POAP_API` (backend server URL)
- `REACT_APP_KEY_XUMM_API` (Xumm App API key, needs to match the key configured in the backend)
- Ensure the backend service is running
- Run the app with `yarn start`

## Available Scripts

In the project directory, you can run:

### `yarn install`

Install dependencies.

### `yarn start`

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.

The page will reload if you make edits.\
You will also see any lint errors in the console.

### `yarn test`

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `yarn build`

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.

## Supported Wallets
- Xumm (installation details [here](https://xumm.app/))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Xumm is rebranding as Xaman so maybe it'd be good to rename them in this project? (With a note like "Xaman, formerly named Xumm, ..."

- GemWallet (installation details [here](https://gemwallet.app/))
11 changes: 11 additions & 0 deletions custom.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
declare module "*.svg" {
import * as React from "react";

const content: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
export default content;
}

declare module "*.svg?url" {
const content: string;
export default content;
}
90 changes: 90 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
"name": "poap-app",
"version": "1.0.0",
"description": "Dashboard for the Proof of Attendance Protocol",
"author": "Riku Block",
"private": true,
"dependencies": {
"@ant-design/colors": "^7.0.0",
"@ant-design/icons": "^5.1.4",
"@emotion/react": "^11.11.0",
"@emotion/styled": "^11.11.0",
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2",
"@fortawesome/react-fontawesome": "^0.2.0",
"@gemwallet/api": "^3.4.0",
"@hookform/resolvers": "^3.1.1",
"@mui/icons-material": "^5.11.16",
"@mui/lab": "^5.0.0-alpha.134",
"@mui/material": "^5.13.2",
"@mui/x-data-grid": "^6.7.0",
"@mui/x-date-pickers": "^6.8.0",
"apexcharts": "^3.42.0",
"axios": "^1.4.0",
"date-fns": "^2.30.0",
"file-saver": "^2.0.5",
"jotai": "^2.1.0",
"notistack": "^3.0.1",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-apexcharts": "^1.4.1",
"react-copy-to-clipboard": "^5.1.0",
"react-device-detect": "^2.2.3",
"react-dom": "^18.2.0",
"react-hook-form": "^7.45.0",
"react-jwt": "^1.2.0",
"react-router-dom": "^6.11.2",
"react-scripts": "5.0.1",
"react-window": "^1.8.9",
"web-vitals": "^2.1.0",
"xrpl": "^2.11.0",
"xumm": "^1.6.1",
"zod": "^3.21.4",
"zustand": "^4.3.8"
},
"scripts": {
"start": "webpack serve --mode development",
"build": "webpack --mode production"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@svgr/webpack": "^8.1.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^13.0.0",
"@testing-library/user-event": "^13.2.1",
"@types/file-saver": "^2.0.5",
"@types/jest": "^27.0.1",
"@types/node": "^16.7.13",
"@types/react": "^18.0.0",
"@types/react-copy-to-clipboard": "^5.0.4",
"@types/react-dom": "^18.0.0",
"@types/react-window": "^1.8.5",
"dotenv-webpack": "^8.0.1",
"esbuild-loader": "^3.0.1",
"html-webpack-plugin": "^5.5.3",
"node-polyfill-webpack-plugin": "^2.0.1",
"ts-loader": "^9.4.3",
"tsconfig-paths-webpack-plugin": "^4.0.1",
"typescript": "^5.1.3",
"webpack": "^5.87.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
}
}
Binary file added public/favicon.ico
Binary file not shown.
28 changes: 28 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Dashboard for the Proof of Attendance Protocol"
/>
<title>POAP Dashboard</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.

To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
7 changes: 7 additions & 0 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import App from "./App";

test("nothing", () => {
render(<App />);
});
43 changes: 43 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { BrowserRouter } from "react-router-dom";
import { Provider as JotaiProvider } from "jotai";
import { SnackbarProvider } from "notistack";

import { createTheme, ThemeProvider } from "@mui/material/styles";
import { CssBaseline } from "@mui/material";
import Slide from "@mui/material/Slide";
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";

import Routes from "routes";
import { Web3Provider } from "connectors/context";
import { AuthProvider } from "components/AuthContext";

function App() {
const theme = createTheme();

return (
<BrowserRouter>
<JotaiProvider>
<Web3Provider>
<AuthProvider>
<ThemeProvider theme={theme}>
<SnackbarProvider
autoHideDuration={10000}
anchorOrigin={{ vertical: "top", horizontal: "right" }}
TransitionComponent={Slide}
maxSnack={3}
>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<CssBaseline />
<Routes />
</LocalizationProvider>
</SnackbarProvider>
</ThemeProvider>
</AuthProvider>
</Web3Provider>
</JotaiProvider>
</BrowserRouter>
);
}

export default App;
27 changes: 27 additions & 0 deletions src/apis/admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import axios from "axios";
import config from "config";

import type { NetworkIdentifier, PlatformStats } from "types";

export type getStatsParams = {
networkId: NetworkIdentifier;
};

export const getStats = async (
jwt: string,
params: getStatsParams
): Promise<PlatformStats> => {
const response = await axios.get(
new URL("/admin/stats", config.apiURL).toString(),
{
headers: {
Authorization: `Bearer ${jwt}`,
},
responseType: "json",
timeout: config.timeout,
params: params,
}
);

return response.data.result as PlatformStats;
};
72 changes: 72 additions & 0 deletions src/apis/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import axios from "axios";
import config from "config";

import { WalletType } from "types";

export const heartbeat = async (): Promise<boolean> => {
const response = await axios.get(
new URL("/auth/heartbeat", config.apiURL).toString(),
{
responseType: "json",
timeout: config.timeout,
}
);

return response.data.result as boolean;
};

export type nonceData = {
pubkey: string;
};

export const nonce = async (data: nonceData): Promise<string> => {
const response = await axios.post(
new URL("/auth/nonce", config.apiURL).toString(),
data,
{
responseType: "json",
timeout: config.timeout,
}
);

return response.data.result as string;
};

export type loginData = {
walletAddress: string;
walletType: WalletType;
data: string;
signature?: string;
claimFlow: boolean;
};

export const login = async (data: loginData): Promise<string> => {
const response = await axios.post(
new URL("/auth/login", config.apiURL).toString(),
data,
{
responseType: "json",
timeout: config.timeout,
}
);

return response.data.result as string;
};

export type refreshResult = string | null;

export const refresh = async (jwt: string): Promise<refreshResult> => {
const response = await axios.post(
new URL("/auth/refresh", config.apiURL).toString(),
{},
{
headers: {
Authorization: `Bearer ${jwt}`,
},
responseType: "json",
timeout: config.timeout,
}
);

return response.data.result as refreshResult;
};
Loading