From 3bf68b8fe8f0f28354c8ba367e20cfe57881c108 Mon Sep 17 00:00:00 2001 From: Brian Patino Date: Fri, 13 Aug 2021 01:11:40 -0400 Subject: [PATCH] Temp/release prep (#62) (#64) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add build-and-test github action * add test server heroku deploy * update action names * add pull request step for autodeploy * add changelog file * reference heroku api key * NextJS scaffolding to get the project started. (#10) * Update README.md * Scaffolding for initial project * Lint fixes * update deps and add jest unit * remove extra deploy step * move test to separate dir Co-authored-by: John <50239591+Icedcool@users.noreply.github.com> Co-authored-by: Brian Patino * Update README.md (#11) Co-authored-by: John <50239591+Icedcool@users.noreply.github.com> * add mongo directory and bboard_v1.json and update readme * update bountyCriteria field, remove publicAddress, and add bountyImage * Feature/mongo db integration (#14) * add environment files * add GET bountie API * fix linting issues * remove push github action * update heroku api key * add secret env * update secrets * add changelog entry * Feature/escrow contract (#15) * Update README.md * v0.1.0 escrow contract * gitignore merge * configure yarn workspaces * fix yarn lint command Co-authored-by: John <50239591+Icedcool@users.noreply.github.com> Co-authored-by: João Henrique Costa <28352619+joaoh9@users.noreply.github.com> Co-authored-by: Brian Patino * Issue-12:added uuid dependency for Bounty Resource Number creation (#13) * Issue-12:added uuid dependency for Bounty Resource Number creation * fix yarn.lock file Co-authored-by: Brian Patino * Feature/netlify integration (#23) * add .toml to react-app * remove .github actions * add mongodb-client-encryption * add netlify status badge * add netlify and nextjs build configs * add bboard_v2.json withh mock data (#24) * add bboard_v2.json withh mock data * update CHANGELOG.md with description of mock json data * update changelog Co-authored-by: Brian Patino * update data model to separate dao member from bounty card * add schema validation for mongo database with validation.js file * update validation.js to validate bountyCard schema for primary key fields * remove bounty from key fields of bboard_v3.json and validation.js * Feature/documentation readme update (#44) * update README.md with project overview, mvp description, and guidance for users * update creating a bounty section in readme * Front end mvp (#28) * Bounty board front end mvp * Fix node version error for deploy * Adding back eslintconfig in package.json * Fix for yarn version * reward option type fix * Configuring husky, close #38 * Making status optional for now * Updated [id]/index to display correct fields, and updated mongoose validation to be consistent with consense validation fields * Added [id]/edit conditional render to block edits on bounties that are not in draft state * refactored previous commit to be logically cleaner by using toLowerCase instead of explicitly checking cases * Small fix for default yarn lint command * Updating husky pre-commit * updated schema validation rules to be consistent with specification, plus requiring the status field. refactored variable names to pull from the correct form variable * Added bounty.status state permissions to delete permissions in [id]/index. Created 400 error page * Updating types and params * Updating bounty type * First attempt at single bounty filter * Refactored single bounty view * Starting filter and draft editing * Removing POST because it is out of scope * Yarn lock for react hook form * Change of schema from date to string Co-authored-by: Behold * fix netlify deployment (#50) * Initial chakra form implementation * Troubleshooting the issue with mongo * Troubleshooting the issue with mongo * Bounty form styling and api refactoring * Cleanup and removing features not needed in MVP * Updating bounty schema * Fixing missing package after merge * Form refactoring to use scale * Bounty props refactor and discord claim linking * add final bounties schema (#41) * add final bounties schema * update final.json according to final_validation.js * adjust to double value * address review comments * add postinstall step and remove 'guild' from 'guildName' * add postinstall step for husky * add precision field * change to scale * update to int * Feature/degen integration sync (#52) * add webhook integration * add build for qa env file * try different build * add root build:qa script * remove mongodb url credentials * manually add configs * move bounty publish to api * remove api console log * wait for publish bounty to finish * feature/54 refactored ? Get Help to Need Help? on buttons below filter * Added link functionality to Need Help? and Give us Feedback buttons in index.tsx under filter * feature/54: Removed use of anchor tag in ColorModeButton due to breaking change and refactored to wrap component in Filter/index.tsx with an accessible link. Refactored prev discord info work * Feature/54 netlify failed on linting error due to unused import. removed * Feature/allow open bounty edit (#57) * Feature/enhance toml env config (#58) * fix webhook post and add conditional logging * small fine tunning * Feature/53 Pagination (#59) * Implemented scrappy client side pagination. Button logic needs updating, as does button styling * feature/53: fixed buggy next page and previous page logic. Implemented an API route to get # bounties in the collection * feature/53: refactored onClick methods. Attempted to wire in Chakra, couldn't get onClick to fire. * feature/53: implemented chakra styling over html buttons w Zberwaldt ! * feature/53 hand merged in Oktal's refactoring of paginated bounties to make it a child component of Bounties and the use of Button rather than chakra.button. refactored math * update readme documentation with ux flow, and updated bot commands. (#51) * update readme documentation with ux flow, and work-in-prog update on bot commands * update README.md to change User Experience Flow and Bot Commands as suggested * add frontend flow to match bot/discord commands in README.md, link to Bounty Board Workflow Notion Page Co-authored-by: Brian * Final front end tweaks (#61) * add prod details * Fix buttons missing once filters was removed (#63) * Fix buttons missing * Made buttons target new tab * Made buttons target new tab Co-authored-by: Oktal <81541283+Oktalize@users.noreply.github.com> Co-authored-by: John <50239591+Icedcool@users.noreply.github.com> Co-authored-by: paulapivat Co-authored-by: João Henrique Costa Co-authored-by: João Henrique Costa <28352619+joaoh9@users.noreply.github.com> Co-authored-by: Behold3th <85538143+Behold3th@users.noreply.github.com> Co-authored-by: @paulapivat <4058461+PaulApivat@users.noreply.github.com> Co-authored-by: Behold Co-authored-by: Oktalize Co-authored-by: Oktal <81541283+Oktalize@users.noreply.github.com> Co-authored-by: John <50239591+Icedcool@users.noreply.github.com> Co-authored-by: paulapivat Co-authored-by: João Henrique Costa Co-authored-by: João Henrique Costa <28352619+joaoh9@users.noreply.github.com> Co-authored-by: Behold3th <85538143+Behold3th@users.noreply.github.com> Co-authored-by: @paulapivat <4058461+PaulApivat@users.noreply.github.com> Co-authored-by: Behold Co-authored-by: Oktalize --- .github/ISSUE_TEMPLATE/bug_report.md | 38 + .github/ISSUE_TEMPLATE/feature_request.md | 20 + .gitignore | 34 +- .husky/pre-commit | 4 + README.md | 78 +- mongo/bounties/bboard_final.json | 87 + mongo/bounties/bboard_v1.json | 76 + mongo/bounties/bboard_v2.json | 232 + mongo/bounties/bboard_v3.json | 102 + mongo/bounties/validation.js | 61 + mongo/bounties/validation_final.js | 91 + netlify.toml | 27 + package.json | 56 +- packages/react-app/.env.prod | 13 + packages/react-app/.env.qa | 13 + packages/react-app/.eslintignore | 3 + packages/react-app/.eslintrc.json | 42 + packages/react-app/.gitignore | 35 + packages/react-app/.prettierignore | 4 + packages/react-app/.prettierrc | 4 + packages/react-app/.prettierrc.js | 10 + packages/react-app/docs/CHANGELOG.md | 13 + packages/react-app/docs/REACT_START_HERE.md | 70 + packages/react-app/next-env.d.ts | 3 + packages/react-app/next-seo.config.ts | 32 + packages/react-app/next.config.js | 4 + packages/react-app/package.json | 68 + packages/react-app/public/favicon.png | Bin 0 -> 607 bytes packages/react-app/public/logo.svg | 1 + .../src/components/global/Footer/index.tsx | 37 + .../src/components/global/Header/Logo.tsx | 15 + .../src/components/global/Header/index.tsx | 102 + .../components/global/SiteLayout/index.tsx | 36 + .../pages/Bounties/Bounty/index.tsx | 174 + .../pages/Bounties/BountyAccordion/index.tsx | 42 + .../pages/Bounties/Filters/index.tsx | 108 + .../components/pages/Bounties/Form/index.tsx | 153 + .../src/components/pages/Bounties/index.tsx | 97 + .../src/components/parts/AccessibleLink.tsx | 22 + .../src/components/parts/ColorModeButton.tsx | 16 + .../src/components/parts/ThemeToggle.tsx | 22 + .../react-app/src/constants/discordInfo.ts | 17 + packages/react-app/src/models/Bounty.ts | 134 + packages/react-app/src/pages/400.tsx | 16 + packages/react-app/src/pages/404.tsx | 16 + packages/react-app/src/pages/[id]/edit.tsx | 32 + packages/react-app/src/pages/[id]/index.tsx | 15 + packages/react-app/src/pages/_app.tsx | 48 + packages/react-app/src/pages/_document.tsx | 41 + .../react-app/src/pages/api/bounties/[id].ts | 86 + .../react-app/src/pages/api/bounties/index.ts | 28 + packages/react-app/src/pages/index.tsx | 12 + .../react-app/src/styles/css/nprogress.css | 81 + packages/react-app/src/styles/customTheme.ts | 73 + packages/react-app/src/styles/index.tsx | 29 + packages/react-app/src/utils/DiscordUtils.ts | 62 + packages/react-app/src/utils/ServiceUtils.ts | 11 + packages/react-app/src/utils/dbConnect.ts | 46 + packages/react-app/tsconfig.json | 29 + packages/react-app/yarn.lock | 4730 +++++++ packages/truffle/contracts/Escrow.sol | 171 + packages/truffle/migrations/1_Escrow.js | 5 + packages/truffle/package.json | 31 + packages/truffle/test/.gitkeep | 0 packages/truffle/test/escrow.test.js | 674 + packages/truffle/truffle-config.js | 31 + src/app/app.js | 1 - yarn.lock | 10629 +++++++++++++++- 68 files changed, 18542 insertions(+), 551 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100755 .husky/pre-commit create mode 100644 mongo/bounties/bboard_final.json create mode 100644 mongo/bounties/bboard_v1.json create mode 100644 mongo/bounties/bboard_v2.json create mode 100644 mongo/bounties/bboard_v3.json create mode 100644 mongo/bounties/validation.js create mode 100644 mongo/bounties/validation_final.js create mode 100644 netlify.toml create mode 100644 packages/react-app/.env.prod create mode 100644 packages/react-app/.env.qa create mode 100644 packages/react-app/.eslintignore create mode 100644 packages/react-app/.eslintrc.json create mode 100644 packages/react-app/.gitignore create mode 100644 packages/react-app/.prettierignore create mode 100644 packages/react-app/.prettierrc create mode 100644 packages/react-app/.prettierrc.js create mode 100644 packages/react-app/docs/CHANGELOG.md create mode 100644 packages/react-app/docs/REACT_START_HERE.md create mode 100644 packages/react-app/next-env.d.ts create mode 100644 packages/react-app/next-seo.config.ts create mode 100644 packages/react-app/next.config.js create mode 100644 packages/react-app/package.json create mode 100644 packages/react-app/public/favicon.png create mode 100644 packages/react-app/public/logo.svg create mode 100644 packages/react-app/src/components/global/Footer/index.tsx create mode 100644 packages/react-app/src/components/global/Header/Logo.tsx create mode 100644 packages/react-app/src/components/global/Header/index.tsx create mode 100644 packages/react-app/src/components/global/SiteLayout/index.tsx create mode 100644 packages/react-app/src/components/pages/Bounties/Bounty/index.tsx create mode 100644 packages/react-app/src/components/pages/Bounties/BountyAccordion/index.tsx create mode 100644 packages/react-app/src/components/pages/Bounties/Filters/index.tsx create mode 100644 packages/react-app/src/components/pages/Bounties/Form/index.tsx create mode 100644 packages/react-app/src/components/pages/Bounties/index.tsx create mode 100644 packages/react-app/src/components/parts/AccessibleLink.tsx create mode 100644 packages/react-app/src/components/parts/ColorModeButton.tsx create mode 100644 packages/react-app/src/components/parts/ThemeToggle.tsx create mode 100644 packages/react-app/src/constants/discordInfo.ts create mode 100644 packages/react-app/src/models/Bounty.ts create mode 100644 packages/react-app/src/pages/400.tsx create mode 100644 packages/react-app/src/pages/404.tsx create mode 100644 packages/react-app/src/pages/[id]/edit.tsx create mode 100644 packages/react-app/src/pages/[id]/index.tsx create mode 100644 packages/react-app/src/pages/_app.tsx create mode 100644 packages/react-app/src/pages/_document.tsx create mode 100644 packages/react-app/src/pages/api/bounties/[id].ts create mode 100644 packages/react-app/src/pages/api/bounties/index.ts create mode 100644 packages/react-app/src/pages/index.tsx create mode 100644 packages/react-app/src/styles/css/nprogress.css create mode 100644 packages/react-app/src/styles/customTheme.ts create mode 100644 packages/react-app/src/styles/index.tsx create mode 100644 packages/react-app/src/utils/DiscordUtils.ts create mode 100644 packages/react-app/src/utils/ServiceUtils.ts create mode 100644 packages/react-app/src/utils/dbConnect.ts create mode 100644 packages/react-app/tsconfig.json create mode 100644 packages/react-app/yarn.lock create mode 100644 packages/truffle/contracts/Escrow.sol create mode 100644 packages/truffle/migrations/1_Escrow.js create mode 100644 packages/truffle/package.json create mode 100644 packages/truffle/test/.gitkeep create mode 100644 packages/truffle/test/escrow.test.js create mode 100644 packages/truffle/truffle-config.js delete mode 100644 src/app/app.js diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..101afd10 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] + +**Smartphone (please complete the following information):** +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..24473dee --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. \ No newline at end of file diff --git a/.gitignore b/.gitignore index 31d83303..9b95fb52 100644 --- a/.gitignore +++ b/.gitignore @@ -68,17 +68,12 @@ typings/ # Yarn Integrity file .yarn-integrity -# dotenv environment variables file -.env -.env.test -.env.qa -.env.prod - # parcel-bundler cache (https://parceljs.org/) .cache # Next.js build output .next +out # Nuxt.js build / generate output .nuxt @@ -110,3 +105,30 @@ dist *.iws *.iml *.ipr + +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env*.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +package-lock.json +contracts/coverage.json +contracts/build + +# Local Netlify folder +.netlify \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 00000000..17df4593 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +yarn workspace @bounty-board/react-app lint-staged diff --git a/README.md b/README.md index cb39a8e7..f5af647b 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,88 @@ # DAO Bounty Board +[![Netlify Status](https://api.netlify.com/api/v1/badges/8e12fc34-94a3-4c7a-8323-fc2b7e1d4d14/deploy-status)](https://app.netlify.com/sites/bounty-board-29081e/deploys) + Project Page: https://www.notion.so/bankless/Bounty-Board-318dc164cc5640cca17e0fb5f484fd90 - ### Specifications: - [Specs page](https://docs.google.com/document/d/1VJXin9Uoqt54JjfQEtyM11XESb2l4C1SSAzgc0kvxIs/edit?usp=sharing) - [Figma](https://www.figma.com/file/venmq7OWr8iRsjR9ecttvc/Untitled?node-id=1%3A7) - [Whimsical](https://whimsical.com/bounty-board-design-bankless-2cPEEZinYKJ2zE2Zvq7iAZ) - [Heroku](https://bounty-board.herokuapp.com/) +- [Possible Queries](https://www.notion.so/Bounty-Board-Queries-33d03a4330454e67b8194aa86274ec34) +- [Data Fields](https://docs.google.com/document/d/10jgHxEpkPlArGlsQH1g22utFrAFh2lK-fbXjbq8KkuU/edit) +- [Personas](https://www.notion.so/Bounty-Board-Personas-8e8f2789775a445c82d13c2a9c545185) +- [Bot flowchart](https://media.discordapp.net/attachments/852736763205910538/857786834682511370/image0.jpg?width=978&height=683) + +# Project Overview + +## Problem + +Currently, Bankless DAO bounties are not in a centralized location causing confusion and makes it challenging for members, new and old, to contribute. Also Level 0's do not have intuitive ways to get involved and earn $BANK other than buying in the secondary markets. + +## Solution + +For the DAO to grow, we need a way to attract, retain and coordinate talent. The bounty board, accessible to members and non-members will connect the DAO to a continually expanding talent pool. + +In addition, we need a way to codify meaningful units of work. Given the diversity of jobs to be done in a DAO, the bounty board allows bounty _creators_ to define and specify the scope of tasks along with expected deliverables. + +Finally, we need a way to formalize the flow of capital, beyond an informal, organic tipping culture that exists to formally recognize contributors for their knowledge, skills and abilities. + +The bounty board will be a key mechanism for coordinating talent, tasks and capital. + +## Minimal Viable Product 1.0 + +### Bounty Card Definition + +For the MVP, we are focusing on the bare requirements for a Bounty Card to be created by a user via DEGEN and/or Frontend UI, with the following key fields: + +- **Title**: Bounty Titles should be like headlines +- **Description**: Provides space to flesh out the scope, deliverables and timeline for the bounty. +- **Criteria**: When is a task considered "done" or "complete"? +- **Reward**: Bounty creator indicates `amount` (i.e., 10000) and `currency` (i.e., $BANK) to be paid for completing the work. +- **HashId**: Auto-generated ID for each bounty. +- **CreatedBy / RequestedBy**: Bot automatically enters bounty creator's `discordHandle`. +- **ClaimedBy**: Bot automatially notes `discordHandle` claiming the bounty. +- **SubmittedBy**: Bot automatically notes `discordHandle` submitting the bounty. + +#### User Experience Flow: Bot in Discord + +The User Experience flow with accompanying bounty status is as follows: + +1. **Draft**: Bounty creator creates new bounty with `/bounty create new`; status is now "Draft" and _not_ shown in Discord. Bounty creator must publish the bounty before it is available to the public. +2. **Publish/Open**: Bounty creator clicks thumbs up emoji 👍 or `/bounty create publish` in Discord, bounty published to #🧀-bounty-board channel and website (url provided); status is now _Open_ on website. +3. **Claim/In Progress**: Within #🧀-bounty-board Bounty _claimer_ click black flag 🏴 or `/bounty claim` to 'start', card changes color in Discord, Bounty creator receives message that bounty has been claimed; Bounty card on website now has _Claimed By_; card status is now "In Progress". +4. **Submit/In Review**: Bounty claimer hits red mail box emoji 📮 in Discord, receives auto-generated message from Bot indicating "bounty in review". The creator of the bounty is notified that the bounty is ready for review. They should reach out to the claimee. Alternatively, user can submit directly through a new bot command `/bounty submit`, entering `HashId`; card status is now "In Review". +5. **Complete/Completed**: Bounty claimer can signal completion ✅ on the post in the #🧀-bounty-board channel or directly through a new bot command `/bounty complete true`; card status is now "Completed". + +#### Bot Commands + +1. Within The Bankless Bot Garage, head to #spam-tastic +2. Enter `/` and see a list of Bots pop up, choose `SERENDIPITY MK-I` + +The following commands are available for Serendipity MK-I: + +/bounty create new +/bounty create publish +/bounty claim +/bounty complete +/bounty list +/bounty delete +/bounty submit + +Refer to the [Bounty Board Commands and Workflow](https://bankless.notion.site/The-Bounty-Board-Commands-and-Workflow-7f15bbc3f2c744afab1cb5f90daac4a2) Notion Page for in-depth details. + +#### User Experience Flow: Frontend + +**Note**: Currently, the frontend mirrors the interaction with the Bot in discord and displays changes in card status. Both Discord/Bot actions and Frontend Statuses are displayed below: + +1. **Discord/Bot: Draft**: Bounty creator creates new bounty with `/bounty create new`; status is now "Draft" and _not_ shown in Discord. Bounty creator must publish the bounty before it is available on the frontend. +2. **Frontend Status: Open**: Bounty creator clicks thumbs up emoji 👍 or `/bounty create publish` in Discord, bounty published to #🧀-bounty-board channel and website (url provided); status is now _Open_ on the frontend. +3. **Discord/Bot: Claim**: Now that a bounty card is _Open_, we can click "Claim It". +4. **Frontend Status: In Progress**: Within #🧀-bounty-board Bounty click black flag 🏴 or `/bounty claim` to 'claim'. A link back to the frontend shows card status as "In Progress" and "Claimed By" claimer's discord handle. +5. **Discord/Bot: Submit**: Bounty claimer hits red mail box emoji 📮 in Discord, receives auto-generated message from Bot indicating "bounty in review". +6. **Frontend Status: In Review**: Card status on the frontend is "In Review". +7. **Discord/Bot: Complete**: Bounty claimer can signal completion ✅ on the post in the #🧀-bounty-board channel. Bounty creator receives message to tip bounty completer. +8. **Frontend Status: Completed**: Work is done. diff --git a/mongo/bounties/bboard_final.json b/mongo/bounties/bboard_final.json new file mode 100644 index 00000000..22b84280 --- /dev/null +++ b/mongo/bounties/bboard_final.json @@ -0,0 +1,87 @@ +[ + { + "_id": "60f6585b453e70eed340e8e3", + "season": 1, + "title": "Make new website landing page", + "description": "Description for new website landing page with specs", + "criteria": "A completed bounty has the following deliverables...", + "reward": { + "currency": "BANK", + "amount": 10000, + "precision": 2 + }, + "applicableGuilds": [ + { + "name": "Developers", + "id": "60f6585b453e70eed340e8e3" + }, + { + "name": "Marketing Guild", + "id": "60f6585b453e70eed340e8e3" + } + ], + "createdBy": { + "isDaoMember": true, + "guildName": "Analytics Guild", + "discordHandle": "paul#8888", + "discordId": "324439902343239764" + }, + "createdAt": "2021-07-20T06:40:56.112Z", + "dueAt": "2021-07-20T06:42:28.853Z", + "activatedAt": "2021-07-20T06:44:33.858Z", + "claimedBy": [ + { + "isDaoMember": false, + "guildName": null, + "discordHandle": "rick#5555", + "discordId": "324423432343239764" + } + ], + "claimedAt": "2021-07-20T07:00:31.166Z", + "completedAt": "2021-07-20T07:00:31.166Z", + "submissionUrl": "https://example.org/rels/v1/bounty_submission", + "submissionNotes": "it took me a long time to work on this bounty", + "status": "Draft", + "statusHistory": [ + { + "status": "Open", + "modifiedAt": "2021-07-20T07:00:31.166Z" + }, + { + "status": "Draft", + "modifiedAt": "2021-07-20T07:00:31.166Z" + }, + { + "status": "In-Progress", + "modifiedAt": "2021-07-20T07:00:31.166Z" + }, + { + "status": "In-Review", + "modifiedAt": "2021-07-20T07:00:31.166Z" + }, + { + "status": "Completed", + "modifiedAt": "2021-07-20T07:00:31.166Z" + }, + { + "status": "Deleted", + "modifiedAt": "2021-07-20T07:00:31.166Z" + } + ], + "hash": "96efcf14fe28a4f17a07a5441b00285b12cbb208bf3c1bdbb030bb95d3e31a8b", + "skillsRequired": [ + "writing", + "design", + "frontend software development", + "backend software development", + "strategic planning", + "data analysis", + "grant writing", + "proposal development", + "team building", + "consensus building", + "marketing", + "sales" + ] + } +] \ No newline at end of file diff --git a/mongo/bounties/bboard_v1.json b/mongo/bounties/bboard_v1.json new file mode 100644 index 00000000..759b5eee --- /dev/null +++ b/mongo/bounties/bboard_v1.json @@ -0,0 +1,76 @@ +[ + { + "//": "Comment: bountyHash message -> bankless dao bounty board" + }, + { + "season" : 2, + "bountyTitle": "A new About Us webpage", + "bountyDescription": "Description of webpage", + "bountyCriteria": "A completed bounty has the following...", + "bountyReward": { + "currency" : "BANK", + "amount" : 5000 + }, + "applicableGuilds": [ + {"guildName": "Marketing Guild"}, + {"guildName": "Treasury Guild"}, + {"guildName": "Developer's Guild"}, + {"guildName": "Analytics Guild"}, + {"guildName": "Writer's Guild"} + ], + "bountyCreatedBy": { + "isDaoMember" : true, + "guildName" : "Analytics Guild", + "discordHandle" : "@paulapivat#8888" + }, + "bountyCreatedAt": "2021-07-10T13:49:51.141Z", + "bountyDueAt" : "2021-09-11T13:49:51.141", + "bountyImage": "https://pbs.twimg.com/profile_images/1389400052448247816/qsOU0pih_400x400.jpg", + "bountyActivatedAt": "2021-07-12T13:49:51.141Z", + "bountyClaimedBy": [ + {"guildName": "Marketing Guild", "discordHandle" : "@random#1234", "publicAddress" : "0x2d94aa3e47d9d5024503ca8491fce9a2fb4da198"} + ], + "bountyClaimedAt": "2021-07-11T13:49:51.141Z", + "bountySubmittedBy": "Developer's Guild", + "bountySubmittedAt": "2021-08-11T13:49:51.141Z", + "bountySubmissionLink": "https://example.org/rels/v1/bounty_submission", + "bountyStatus": [ + { + "status" : "Open", + "openAt" : "2021-07-10T13:49:51.141Z" + }, + { + "status" : "Draft", + "draftAt" : "2021-07-10T13:49:51.141Z" + }, + { + "status" : "In-Progress", + "progressAt" : "2021-07-10T13:49:51.141Z" + }, + { + "status" : "In-Review", + "reviewAt" : "2021-07-10T13:49:51.141Z" + }, + { + "status" : "Completed", + "completedAt" : "2021-07-10T13:49:51.141Z" + }, + { + "status" : "Deleted", + "closedAt" : "2021-07-10T13:49:51.141Z" + } + ], + "bountyHash" : "96efcf14fe28a4f17a07a5441b00285b12cbb208bf3c1bdbb030bb95d3e31a8b", + "skillsRequired" : [ + "writing", + "design", + "software development", + "strategic planning", + "data analysis", + "grant writing", + "proposal development", + "team building", + "marketing" + ] + } +] \ No newline at end of file diff --git a/mongo/bounties/bboard_v2.json b/mongo/bounties/bboard_v2.json new file mode 100644 index 00000000..1dc98132 --- /dev/null +++ b/mongo/bounties/bboard_v2.json @@ -0,0 +1,232 @@ +[ + { + "season": 3, + "bounty": "Thus box music year fund level.", + "bountyDescription": "Visit address me item.", + "bountyCriteria": "Hand draw get listen significant officer.", + "bountyReward": { + "currency": "BTC", + "amount": 47685 + }, + "applicableGuilds": [ + { + "guildName": "Analytics Guild" + }, + { + "guildName": "Treasury Guild" + } + ], + "bountyCreatedBy": { + "isDaoMember": true, + "guildName": "Analytics Guild", + "discordHandle": "@delta#2222" + }, + "bountyCreatedAt": "2021-07-12", + "bountyDueAt": "2021-12-22", + "bountyImage": "https://pbs.twimg.com/profile_images/1389400052448247816/qsOU0pih_400x400.jpg", + "bountyActivatedAt": "2021-07-12", + "bountyClaimedBy": { + "guildName": "Treasury Guild", + "discordHandle": "@alice#1234" + }, + "bountyClaimedAt": "2021-07-12", + "bountySubmittedBy": "Writer's Guild", + "bountySubmittedAt": "2021-07-12", + "bountySubmissionLink": "www.example.org", + "bountyStatus": [ + { + "status": "Draft", + "bountyStatusTime": "2022-05-03" + } + ], + "bountyHash": "eac65c7b6f5a37df3dee998a0afcfde7", + "skillsRequired": [ + "marketing", + "strategic planning" + ] + }, + { + "season": 10, + "bounty": "Pull sit their will.", + "bountyDescription": "Impact story talk site everybody particular or.", + "bountyCriteria": "Some move between plant where marriage.", + "bountyReward": { + "currency": "BTC", + "amount": 11239 + }, + "applicableGuilds": [ + { + "guildName": "Marketing Guild" + }, + { + "guildName": "Developer's Guild" + } + ], + "bountyCreatedBy": { + "isDaoMember": false, + "guildName": "Marketing Guild", + "discordHandle": "@delta#2222" + }, + "bountyCreatedAt": "2021-07-12", + "bountyDueAt": "2022-03-27", + "bountyImage": "https://pbs.twimg.com/profile_images/1389400052448247816/qsOU0pih_400x400.jpg", + "bountyActivatedAt": "2021-07-12", + "bountyClaimedBy": { + "guildName": "Marketing Guild", + "discordHandle": "@delta#2222" + }, + "bountyClaimedAt": "2021-07-12", + "bountySubmittedBy": "Treasury Guild", + "bountySubmittedAt": "2021-07-12", + "bountySubmissionLink": "www.example.net", + "bountyStatus": [ + { + "status": "Open", + "bountyStatusTime": "2022-02-25" + } + ], + "bountyHash": "8c38d010d86de1feda23f5d5727e78f0", + "skillsRequired": [ + "writing", + "data analysis" + ] + }, + { + "season": 2, + "bounty": "Condition daughter current system thing go reduce.", + "bountyDescription": "Other quite experience high.", + "bountyCriteria": "Space instead senior spend history better population.", + "bountyReward": { + "currency": "BANK", + "amount": 40975 + }, + "applicableGuilds": [ + { + "guildName": "Writer's Guild" + }, + { + "guildName": "Developer's Guild" + } + ], + "bountyCreatedBy": { + "isDaoMember": true, + "guildName": "Developer's Guild", + "discordHandle": "@delta#2222" + }, + "bountyCreatedAt": "2021-07-12", + "bountyDueAt": "2021-10-10", + "bountyImage": "https://pbs.twimg.com/profile_images/1389400052448247816/qsOU0pih_400x400.jpg", + "bountyActivatedAt": "2021-07-12", + "bountyClaimedBy": { + "guildName": "Treasury Guild", + "discordHandle": "@delta#2222" + }, + "bountyClaimedAt": "2021-07-12", + "bountySubmittedBy": "Developer's Guild", + "bountySubmittedAt": "2021-07-12", + "bountySubmissionLink": "www.example.com", + "bountyStatus": [ + { + "status": "In-Progress", + "bountyStatusTime": "2021-10-18" + } + ], + "bountyHash": "aaf853be8ca2f1e30b4c83b1d4bfcbde", + "skillsRequired": [ + "design", + "data analysis" + ] + }, + { + "season": 10, + "bounty": "Study without set staff.", + "bountyDescription": "Series former its five off strategy.", + "bountyCriteria": "Term walk arrive nothing name onto.", + "bountyReward": { + "currency": "ETH", + "amount": 35450 + }, + "applicableGuilds": [ + { + "guildName": "Treasury Guild" + }, + { + "guildName": "Developer's Guild" + } + ], + "bountyCreatedBy": { + "isDaoMember": false, + "guildName": "Writer's Guild", + "discordHandle": "@alice#1234" + }, + "bountyCreatedAt": "2021-07-12", + "bountyDueAt": "2022-06-05", + "bountyImage": "https://pbs.twimg.com/profile_images/1389400052448247816/qsOU0pih_400x400.jpg", + "bountyActivatedAt": "2021-07-12", + "bountyClaimedBy": { + "guildName": "Developer's Guild", + "discordHandle": "@delta#2222" + }, + "bountyClaimedAt": "2021-07-12", + "bountySubmittedBy": "Developer's Guild", + "bountySubmittedAt": "2021-07-12", + "bountySubmissionLink": "www.example.org", + "bountyStatus": [ + { + "status": "Open", + "bountyStatusTime": "2021-08-08" + } + ], + "bountyHash": "72e04fe31953195ab0911e96cf59364f", + "skillsRequired": [ + "strategic planning", + "writing" + ] + }, + { + "season": 2, + "bounty": "Instead range most outside government without above.", + "bountyDescription": "Say tree effect wait avoid.", + "bountyCriteria": "Lot year meet analysis media cold local.", + "bountyReward": { + "currency": "ETH", + "amount": 13166 + }, + "applicableGuilds": [ + { + "guildName": "Marketing Guild" + }, + { + "guildName": "Treasury Guild" + } + ], + "bountyCreatedBy": { + "isDaoMember": true, + "guildName": "Treasury Guild", + "discordHandle": "@delta#2222" + }, + "bountyCreatedAt": "2021-07-12", + "bountyDueAt": "2022-04-16", + "bountyImage": "https://pbs.twimg.com/profile_images/1389400052448247816/qsOU0pih_400x400.jpg", + "bountyActivatedAt": "2021-07-12", + "bountyClaimedBy": { + "guildName": "Marketing Guild", + "discordHandle": "@alice#1234" + }, + "bountyClaimedAt": "2021-07-12", + "bountySubmittedBy": "Developer's Guild", + "bountySubmittedAt": "2021-07-12", + "bountySubmissionLink": "www.example.net", + "bountyStatus": [ + { + "status": "Draft", + "bountyStatusTime": "2021-11-09" + } + ], + "bountyHash": "b1df4577e03129eb96de415eace2bd2e", + "skillsRequired": [ + "marketing", + "team building" + ] + } +] \ No newline at end of file diff --git a/mongo/bounties/bboard_v3.json b/mongo/bounties/bboard_v3.json new file mode 100644 index 00000000..55d722d1 --- /dev/null +++ b/mongo/bounties/bboard_v3.json @@ -0,0 +1,102 @@ +[ + { + "//": "Comment: bountyHash message -> bankless dao bounty board" + }, + { + "_id" : ObjectId("60f6558d453e70eed340e8e0"), + "isDaoMember" : true, + "guildName" : "Analytics Guild", + "discordHandle" : "@paul#8888" + }, + { + "_id" : ObjectId("60f6558d453e70eed340e8e1"), + "isDaoMember" : false, + "guildName" : null, + "discordHandle" : "@rick#5555" + }, + { + "_id" : ObjectId("60f6558d453e70eed340e8e2"), + "isDaoMember" : true, + "guildName" : "Developers Guild", + "discordHandle" : "@james#7777" + }, + { + "_id" : ObjectId("60f6585b453e70eed340e8e3"), + "season" : 1, + "Title" : "Make new website landing page", + "Description" : "Description for new website landing page with specs", + "Criteria" : "A completed bounty has the following deliverables...", + "Reward" : { + "currency" : "BANK", + "amount" : 10000 + }, + "applicableGuilds" : [ + { + "guildName" : "Developers Guild" + }, + { + "guildName" : "Marketing Guild" + } + ], + "CreatedBy" : { + "user" : ObjectId("60f6558d453e70eed340e8e0") + }, + "CreatedAt" : ISODate("2021-07-20T06:40:56.112Z"), + "DueAt" : ISODate("2021-07-20T06:42:28.853Z"), + "Image" : "https://pbs.twimg.com/profile_images/1389400052448247816/qsOU0pih_400x400.jpg", + "ActivatedAt" : ISODate("2021-07-20T06:44:33.858Z"), + "ClaimedBy" : [ + { + "user" : ObjectId("60f6558d453e70eed340e8e1") + }, + { + "user" : ObjectId("60f6558d453e70eed340e8e2") + } + ], + "ClaimedAt" : ISODate("2021-07-20T07:00:31.166Z"), + "SubmittedBy" : "Developer's Guild", + "SubmittedAt" : ISODate("2021-07-20T07:01:34.700Z"), + "SubmissionLink" : "https://example.org/rels/v1/bounty_submission", + "Status" : [ + { + "status" : "Open", + "openAt" : ISODate("2021-07-20T07:00:31.166Z") + }, + { + "status" : "Draft", + "draftAt" : ISODate("2021-07-20T07:00:31.166Z") + }, + { + "status" : "In-Progress", + "progressAt" : ISODate("2021-07-20T07:00:31.166Z") + }, + { + "status" : "In-Review", + "reviewAt" : ISODate("2021-07-20T07:00:31.166Z") + }, + { + "status" : "Completed", + "completedAt" : ISODate("2021-07-20T07:00:31.166Z") + }, + { + "status" : "Deleted", + "deletedAt" : ISODate("2021-07-20T07:00:31.166Z") + } + ], + "Hash" : "96efcf14fe28a4f17a07a5441b00285b12cbb208bf3c1bdbb030bb95d3e31a8b", + "skillsRequired" : [ + "writing", + "design", + "frontend software development", + "backend software development", + "strategic planning", + "data analysis", + "grant writing", + "proposal development", + "team building", + "consensus building", + "marketing", + "sales" + ] + } +] \ No newline at end of file diff --git a/mongo/bounties/validation.js b/mongo/bounties/validation.js new file mode 100644 index 00000000..1f5f24f4 --- /dev/null +++ b/mongo/bounties/validation.js @@ -0,0 +1,61 @@ +db.createCollection("bountyCard", { + validator: { + $jsonSchema: { + bsonType: "object", + required: [ + "season", + "Title", + "Description", + "Criteria", + "Reward", + "CreatedBy", + "CreatedAt", + "DueAt", + ], + properties: { + season: { + bsonType: "double", + description: "must be a double and is required", + }, + Title: { + bsonType: "string", + description: "must be a string and is required", + }, + Description: { + bsonType: "string", + description: "must be an string and is required", + }, + Criteria: { + bsonType: "string", + description: "must be an string and is required", + }, + Reward: { + bsonType: "object", + description: "must be an object and is required", + properties: { + currency: { + bsonType: "string", + description: "must be a string and is required", + }, + amount: { + bsonType: "double", + description: "must be a double and is required", + }, + }, + }, + CreatedBy: { + bsonType: "objectId", + description: "must be an objectId and is required", + }, + CreatedAt: { + bsonType: "date", + description: "must be a date and is required", + }, + DueAt: { + bsonType: "date", + description: "must be a date and is required", + }, + }, + }, + }, +}); diff --git a/mongo/bounties/validation_final.js b/mongo/bounties/validation_final.js new file mode 100644 index 00000000..fbfc0f1e --- /dev/null +++ b/mongo/bounties/validation_final.js @@ -0,0 +1,91 @@ +db.createCollection("bounties", { + validator: { + $jsonSchema: { + bsonType: "object", + required: [ + "season", + "title", + "description", + "criteria", + "reward", + "createdBy", + "createdAt", + "dueAt", + 'status', + 'statusHistory' + ], + properties: { + season: { + bsonType: "int", + description: "the current season of the DAO, nonzero integer, /^[0,9]+$/", + }, + title: { + bsonType: "string", + description: "a short title about the bounty, /^[\\w\\s.!@#$%&,?']{1,50}$/", + }, + description: { + bsonType: "string", + description: "a short description of the bounty, /^[\\w\\s.!@#$%&,?']{1,250}$/", + }, + criteria: { + bsonType: "string", + description: "absolutely required work for bounty to be Completed, /^[\\w\\s.!@#$%&,?']{1,250}$/", + }, + status: { + bsonType: "string", + description: "the current status of the bounty", + }, + statusHistory: { + bsonType: "array", + description: "the history of the status of the bounty", + }, + reward: { + bsonType: "object", + description: "how much to be distributed to worker once bounty is Completed", + required: [ + "currency", + "amount", + "scale", + ], + properties: { + currency: { + bsonType: "string", + description: "the currency denomination i.e ETH", + }, + amount: { + bsonType: "int", + description: "the amount to be rewarded i.e 1000", + }, + scale: { + bsonType: 'int', + description: 'the decimal value for the given amount' + }, + }, + }, + createdBy: { + bsonType: "object", + description: "user object who created the bounty", + required: ["discordHandle", "discordId"], + properties: { + discordHandle: { + bsonType: "string", + description: "the discord tag i.e hydrabolt#0001", + }, + discordId: { + bsonType: "string", + description: "the discord internal id, i.e 324439906234239764", + } + } + }, + createdAt: { + bsonType: "string", + description: "ISO8601 date string for when the bounty was created", + }, + dueAt: { + bsonType: "string", + description: "ISO8601 date string for when the bounty is due (default to end of season)", + }, + }, + }, + }, +}); diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 00000000..30a05f25 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,27 @@ +# https://docs.netlify.com/configure-builds/file-based-configuration/ +# Settings in the [build] context are global and are applied to all contexts +# unless otherwise overridden by more specific contexts. +[build] + command = "yarn build:qa" + + # Directory that contains the deploy-ready HTML files and assets generated by + # the build. This is relative to the base directory if one has been set, or the + # root directory if a base has not been set. This sample publishes the + # directory located at the absolute path "root/project/build-output" + publish = "packages/react-app/dist" + +[build.environment] + NODE_VERSION = "14.17.5" + +[dev] + command = "yarn dev" + +[[plugins]] + package = "@netlify/plugin-nextjs" + +# Production context: +# All deploys from the main repository branch +# will inherit these settings. +[context.production] + command = "yarn build:prod" + publish = "packages/react-app/dist" diff --git a/package.json b/package.json index 06bf51f1..29bac891 100644 --- a/package.json +++ b/package.json @@ -1,30 +1,40 @@ { - "name": "bounty-board", - "version": "0.1.0", - "description": "This web app displays the bounties that are available for DAO members to claim.", - "main": "app.js", - "repository": "https://github.com/BanklessDAO/bounty-board", - "author": "Bankless DAO", - "license": "MIT", + "name": "@bounty-board/monorepo", + "version": "1.0.0", "private": true, - "bugs": { - "url": "https://github.com/BanklessDAO/bounty-board/issues" - }, - "homepage": "https://github.com/BanklessDAO/bounty-board", "scripts": { - "test": "mocha -r dotenv/config src/test/**/*.test.js", - "qa": "node -r dotenv/config src/app/app.js dotenv_config_path=.env.qa", - "start": "node -r dotenv/config src/app/app.js" + "start": "yarn workspace @bounty-board/react-app start", + "dev": "yarn workspace @bounty-board/react-app dev", + "build": "yarn workspace @bounty-board/react-app build", + "build:qa": "yarn workspace @bounty-board/react-app build:qa", + "build:prod": "yarn workspace @bounty-board/react-app build:prod", + "lint": "yarn workspace @bounty-board/react-app lint", + "test": "yarn workspace @bounty-board/react-app test", + "react-app:lint-staged": "yarn workspace @bounty-board/react-app lint-staged", + "react-app:type-check": "yarn workspace @bounty-board/react-app type-check", + "react-app:format": "yarn workspace @bounty-board/react-app format", + "react-app:test-all": "yarn workspace @bounty-board/react-app test-all", + "truffle:test": "yarn workspace @bounty-board/escrow test", + "truffle:start": "yarn workspace @bounty-board/escrow start", + "truffle:coverage": "yarn workspace @bounty-board/escrow coverage", + "postinstall": "npx husky install" }, - "dependencies": { - "dotenv": "^10.0.0", - "mocha": "^9.0.0", - "mongodb": "^3.6.9", - "nock": "^13.1.0" + "husky": { + "hooks": { + "pre-commit": "react-app:lint-staged" + } }, - "devDependencies": {}, - "engines": { - "node": "14.17.0" + "dependencies": {}, + "workspaces": { + "packages": [ + "packages/*" + ], + "nohoist": [ + "**/truffle", + "**/truffle/**" + ] }, - "engineStrict": true + "devDependencies": { + "husky": "^7.0.1" + } } diff --git a/packages/react-app/.env.prod b/packages/react-app/.env.prod new file mode 100644 index 00000000..a131f7ac --- /dev/null +++ b/packages/react-app/.env.prod @@ -0,0 +1,13 @@ +MONGODB_DB=bountyboard +MONGODB_URI= + +NEXT_PUBLIC_DISCORD_SERVER_ID=834499078434979890 +NEXT_PUBLIC_DISCORD_CHANNEL_BOUNTY_BOARD_ID=850402063741091880 + +# Public Environments +NEXT_PUBLIC_DAO_CURRENT_SEASON=1 +NEXT_PUBLIC_DAO_CURRENT_SEASON_END_DATE=2021-08-31T04:00:00.000Z + +# URLs +NEXT_PUBLIC_DAO_BOUNTY_BOARD_URL=https://bountyboard.bankless.community +DISCORD_BOUNTY_BOARD_WEBHOOK= \ No newline at end of file diff --git a/packages/react-app/.env.qa b/packages/react-app/.env.qa new file mode 100644 index 00000000..1565becd --- /dev/null +++ b/packages/react-app/.env.qa @@ -0,0 +1,13 @@ +MONGODB_DB=bountyboard +MONGODB_URI= + +NEXT_PUBLIC_DISCORD_SERVER_ID=851552281249972254 +NEXT_PUBLIC_DISCORD_CHANNEL_BOUNTY_BOARD_ID=869964294865977425 + +# Public Environments +NEXT_PUBLIC_DAO_CURRENT_SEASON=1 +NEXT_PUBLIC_DAO_CURRENT_SEASON_END_DATE=2021-08-31T04:00:00.000Z + +# URLs +NEXT_PUBLIC_DAO_BOUNTY_BOARD_URL=https://develop--bounty-board-29081e.netlify.app/ +DISCORD_BOUNTY_BOARD_WEBHOOK=https://discord.com/api/webhooks/873289859308073070/cj4sCbAABT3CpOC5f-5XTbJvkDimqEGAye-CFUYGos6V_euKo9jlKXhpJu051ZoNkora \ No newline at end of file diff --git a/packages/react-app/.eslintignore b/packages/react-app/.eslintignore new file mode 100644 index 00000000..35e915e5 --- /dev/null +++ b/packages/react-app/.eslintignore @@ -0,0 +1,3 @@ +**/node_modules/* +**/out/* +**/.next/* diff --git a/packages/react-app/.eslintrc.json b/packages/react-app/.eslintrc.json new file mode 100644 index 00000000..f9657030 --- /dev/null +++ b/packages/react-app/.eslintrc.json @@ -0,0 +1,42 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended" + // Uncomment the following lines to enable eslint-config-prettier + // Is not enabled right now to avoid issues with the Next.js repo + // "prettier", + ], + "env": { + "es6": true, + "browser": true, + "jest": true, + "node": true + }, + "settings": { + "react": { + "version": "detect" + } + }, + "rules": { + "react/react-in-jsx-scope": 0, + "react/display-name": 0, + "react/prop-types": 0, + "@typescript-eslint/explicit-function-return-type": 0, + "@typescript-eslint/explicit-member-accessibility": 0, + "@typescript-eslint/indent": 0, + "@typescript-eslint/member-delimiter-style": 0, + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-var-requires": 0, + "@typescript-eslint/no-use-before-define": 0, + "@typescript-eslint/no-unused-vars": [ + 2, + { + "argsIgnorePattern": "^_" + } + ], + "react/no-unescaped-entities": 1 + } +} diff --git a/packages/react-app/.gitignore b/packages/react-app/.gitignore new file mode 100644 index 00000000..74b75863 --- /dev/null +++ b/packages/react-app/.gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel diff --git a/packages/react-app/.prettierignore b/packages/react-app/.prettierignore new file mode 100644 index 00000000..09c508e8 --- /dev/null +++ b/packages/react-app/.prettierignore @@ -0,0 +1,4 @@ +# Ignore : +build +.next +node_modules \ No newline at end of file diff --git a/packages/react-app/.prettierrc b/packages/react-app/.prettierrc new file mode 100644 index 00000000..b2095be8 --- /dev/null +++ b/packages/react-app/.prettierrc @@ -0,0 +1,4 @@ +{ + "semi": false, + "singleQuote": true +} diff --git a/packages/react-app/.prettierrc.js b/packages/react-app/.prettierrc.js new file mode 100644 index 00000000..907d02e3 --- /dev/null +++ b/packages/react-app/.prettierrc.js @@ -0,0 +1,10 @@ +module.exports = { + tabWidth: 2, + printWidth: 80, + endOfLine: 'auto', + arrowParens: 'always', + semi: true, + useTabs: false, + singleQuote: true, + bracketSpacing: true, +}; diff --git a/packages/react-app/docs/CHANGELOG.md b/packages/react-app/docs/CHANGELOG.md new file mode 100644 index 00000000..bcb8d9fc --- /dev/null +++ b/packages/react-app/docs/CHANGELOG.md @@ -0,0 +1,13 @@ +# CHANGELOG + +## 1.0.0-beta (2021-08-12) + +1. Add github and heroku actions integration, initialize react-create app +2. Import next.js bankless dao template +3. Add mongodb integration +4. Add netlify integration with configuration +5. Add mock json data for mongodb compass testing +6. Fix netlify deployment and add .github docs +7. Add webhook integration for posting bounties +8. Allow editing of OPEN bounties +9. Add HashId to bounties display, disable connect wallet, set dark mode as default, make logo a link diff --git a/packages/react-app/docs/REACT_START_HERE.md b/packages/react-app/docs/REACT_START_HERE.md new file mode 100644 index 00000000..02aac3f6 --- /dev/null +++ b/packages/react-app/docs/REACT_START_HERE.md @@ -0,0 +1,70 @@ +# Getting Started with Create React App + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). + +## Available Scripts + +In the project directory, you can run: + +### `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. + +### `yarn eject` + +**Note: this is a one-way operation. Once you `eject`, you can’t go back!** + +If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. + +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. + +You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) + +### Analyzing the Bundle Size + +This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) + +### Making a Progressive Web App + +This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) + +### Advanced Configuration + +This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) + +### Deployment + +This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) + +### `yarn build` fails to minify + +This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/packages/react-app/next-env.d.ts b/packages/react-app/next-env.d.ts new file mode 100644 index 00000000..c6643fda --- /dev/null +++ b/packages/react-app/next-env.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// diff --git a/packages/react-app/next-seo.config.ts b/packages/react-app/next-seo.config.ts new file mode 100644 index 00000000..d90461e4 --- /dev/null +++ b/packages/react-app/next-seo.config.ts @@ -0,0 +1,32 @@ +const title = 'Bankless Bounty Board'; +const description = + 'Bankless Bounty Board'; +const url = 'https://bountyboard.bankless.community'; + +const SEO = { + title, + description, + canonical: url, + openGraph: { + type: 'website', + url, + title, + description, + images: [ + { + url: `https://www.bankless.community/logo.svg`, + alt: title, + width: 2048, + height: 1170, + }, + ], + }, + twitter: { + cardType: 'summary_large_image', + handle: '@banklessdao', + site: '@banklessdao', + }, + additionalLinkTags: [{ rel: 'icon', href: '/favicon.png' }], +}; + +export default SEO; diff --git a/packages/react-app/next.config.js b/packages/react-app/next.config.js new file mode 100644 index 00000000..83c12d0d --- /dev/null +++ b/packages/react-app/next.config.js @@ -0,0 +1,4 @@ +module.exports = { + distDir: 'dist', + webpack5: true, +} \ No newline at end of file diff --git a/packages/react-app/package.json b/packages/react-app/package.json new file mode 100644 index 00000000..4986f2d3 --- /dev/null +++ b/packages/react-app/package.json @@ -0,0 +1,68 @@ +{ + "name": "@bounty-board/react-app", + "version": "0.1.0", + "homepage": ".", + "description": "This web app displays the bounties that are available for DAO members to claim.", + "repository": "https://github.com/BanklessDAO/bounty-board", + "license": "MIT", + "bugs": { + "url": "https://github.com/BanklessDAO/bounty-board/issues" + }, + "eslintConfig": { + "extends": "react-app" + }, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "build:qa": "env-cmd -f .env.qa next build", + "build:prod": "env-cmd -f .env.prod next build", + "type-check": "tsc --pretty --noEmit --skipLibCheck --esModuleInterop --strict --jsx preserve", + "export": "next export", + "lint": "next lint", + "format": "prettier --write src" + }, + "lint-staged": { + "*.@(ts|tsx)": [ + "yarn run type-check", + "yarn lint src --fix -d", + "yarn format" + ] + }, + "dependencies": { + "@chakra-ui/react": "^1.6.5", + "@emotion/react": "^11.1.5", + "@emotion/styled": "^11.3.0", + "@fontsource/lexend": "^4.5.0", + "@hookform/resolvers": "^2.7.1", + "@netlify/plugin-nextjs": "^3.8.0", + "@typescript-eslint/eslint-plugin": "^4.28.3", + "env-cmd": "^10.1.0", + "framer-motion": "^4.1.17", + "mongodb-client-encryption": "^1.2.6", + "mongoose": "^5.13.4", + "next": "^11.0.0", + "next-seo": "^4.26.0", + "nprogress": "^0.2.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-hook-form": "^7.12.2", + "react-icons": "^4.2.0", + "swr": "^0.5.6", + "yup": "^0.32.9" + }, + "devDependencies": { + "@types/node": "^16.4.7", + "@types/nprogress": "^0.2.0", + "@types/react": "^17.0.14", + "eslint": "^7.30.0", + "eslint-config-next": "^11.0.1", + "lint-staged": "^11.0.0", + "prettier": "^2.3.2", + "typescript": "^4.3.5" + }, + "engines": { + "yarn": "1.x", + "node": "~14.17.0" + } +} diff --git a/packages/react-app/public/favicon.png b/packages/react-app/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..4bec56fdac30df63617f5b2d8544f8d4af7f62b3 GIT binary patch literal 607 zcmV-l0-*hgP)z{$QiY)TG+uU)|ww*x7jMJAsQ>Ot4W= zCsXgjn)h^?jg?hZs(7mIPy)MvkV+=OYPCUYOEa?^?C)|P+R%qxfM}?%6C%~s*0S+M zqeHT00@F4V78}tTyt&C7RBPj0+n~g z=-4=4gR;C!NdHZ%V_~X}!{|GdU88 z!qnu1W)_O#c_(CI$k7LF75U$FbpKq?1rkVL@bWePBow+p;`6%<9@=a2P6AR1LDir9 t1f2vyCqd9j5Q>5XURLa(Sug \ No newline at end of file diff --git a/packages/react-app/src/components/global/Footer/index.tsx b/packages/react-app/src/components/global/Footer/index.tsx new file mode 100644 index 00000000..35bf89ef --- /dev/null +++ b/packages/react-app/src/components/global/Footer/index.tsx @@ -0,0 +1,37 @@ +import { Box, Flex, HStack, Text } from '@chakra-ui/react' +import AccessibleLink from '../../../components/parts/AccessibleLink' +import ColorModeButton from '../../../components/parts/ColorModeButton' + +import { discordSupportChannelUrl } from '../../../constants/discordInfo' +import { feedbackUrl } from '../../../constants/discordInfo' + +const Footer = (): JSX.Element => { + return ( + + + {/* + Mirror Substack Discord Twitter Github + */} + + + Give us Feedback + + + + Need Help? + + + + + © {new Date().getFullYear()} Bankless DAO + + ) +} + +export default Footer diff --git a/packages/react-app/src/components/global/Header/Logo.tsx b/packages/react-app/src/components/global/Header/Logo.tsx new file mode 100644 index 00000000..f75d935c --- /dev/null +++ b/packages/react-app/src/components/global/Header/Logo.tsx @@ -0,0 +1,15 @@ +import React from 'react' +import { Box, BoxProps, Image, Link as ChakraLink } from '@chakra-ui/react' +import Link from 'next/link' + +export default function Logo(props: BoxProps): JSX.Element { + return ( + + + + Bankless DAO + + + + ) +} diff --git a/packages/react-app/src/components/global/Header/index.tsx b/packages/react-app/src/components/global/Header/index.tsx new file mode 100644 index 00000000..1d7fae17 --- /dev/null +++ b/packages/react-app/src/components/global/Header/index.tsx @@ -0,0 +1,102 @@ +import React, { useState } from 'react' +import { Box, Flex, Text, Stack, useColorModeValue } from '@chakra-ui/react' + +import { RiMenuFill, RiCloseFill } from 'react-icons/ri' + +import Logo from './Logo' +import ThemeToggle from '../../parts/ThemeToggle' +import AccessibleLink from '../../parts/AccessibleLink' +import ColorModeButton from '../../parts/ColorModeButton' + +const CloseIcon = ({ color }: { color: string }) => ( + +) +const MenuIcon = ({ color }: { color: string }) => ( + +) + +const NavBar: React.FC = (props): JSX.Element => { + const [isOpen, setIsOpen] = useState(false) + const toggle = () => setIsOpen(!isOpen) + + return ( + + + + + + ) +} + +const MenuToggle = ({ + toggle, + isOpen, +}: { + toggle: VoidFunction + isOpen: boolean +}): JSX.Element => { + const fgColor = useColorModeValue('black', 'white') + return ( + + {isOpen ? : } + + ) +} + +const MenuItem = ({ + children, + to = '/', + newTab, + ...rest +}: { + children?: React.ReactNode + isLast?: boolean + to: string + newTab?: boolean +}): JSX.Element => ( + + + {children} + + +) + +const MenuLinks = ({ isOpen }: { isOpen: boolean }): JSX.Element => ( + + + {/*Bounty Board*/} + {/*TODO: enabled this with web3 integration */} + {/**/} + {/* Connect Wallet{' '}*/} + {/**/} + + Join DAO{' '} + + + + +) + +const NavBarContainer: React.FC = (props): JSX.Element => ( + + {props.children} + +) + +export default NavBar diff --git a/packages/react-app/src/components/global/SiteLayout/index.tsx b/packages/react-app/src/components/global/SiteLayout/index.tsx new file mode 100644 index 00000000..3d226dbd --- /dev/null +++ b/packages/react-app/src/components/global/SiteLayout/index.tsx @@ -0,0 +1,36 @@ +import { Box, Stack, Heading } from '@chakra-ui/react' +import { ReactNode } from 'react' + +import Header from '../Header' +import Footer from '../Footer' + +type LayoutProps = { + children: ReactNode + title: string +} + +const SiteLayout = ({ children, title }: LayoutProps): JSX.Element => { + return ( + <> +
+ + + + {title} + + {children} + + +