Giter Site home page Giter Site logo

verida / verida-one-webapp Goto Github PK

View Code? Open in Web Editor NEW
5.0 5.0 2.0 51.65 MB

Verida One is a public, decentralized platform that allows you to showcase who you are across Web2 and Web3, online and IRL

Home Page: https://www.verida.one

License: ISC License

HTML 0.86% CSS 0.57% TypeScript 93.14% JavaScript 5.43%
decentralized identity nft personal-data profile sbt web3

verida-one-webapp's Introduction

Verida One Webapp

Overview

Your identity in one place

Development

The application is composed of a frontend and a server. The server merely allows the update of the meta tags dynamically before serving the index.html.

On a local development environment, due to current limitations, the server only serves the build folder of the frontend, so doesn't allow hot reloading of the frontend.

We recommend to focus on either the frontend or the server at a time.

Install

// frontend
yarn install

// server
cd ./server
yarn install

Some environment variables are required for the application to run. Have a look at the provided examples.

Copy .env.example, rename it to .env and modify the variables for your local environment.

// frontend
cp .env.example .env

//server
cd ./server
cp .env.example .env

Run

The frontend can be started with its dedicated development server supporting hot reloading:

// frontend
yarn run start:dev

The server can be started via the following command (serving the build folder of the frontend):

// server
cd ./server
yarn run start:dev

Features in development

Non production-ready features must be disabled in Production deployment. To ensure this, add a feature flag in /lib/config. It can be simply based on the existing process.env.REACT_APP_ENABLE_DEV_FEATURES=true or it can have a dedicated environment variable.

Check for .env.example for the exact variables.

Mock data

In a similar way as the development features, a set of mock data is available. It can be enabled by setting the environment variable REACT_APP_ENABLE_MOCK_DATA=true.

The mock profile can found by searching for the Username "ryan-demo.vda".

Linting and Formatting

We use eslint for the linting and prettier for the formatting.

Scripts are available to check and fix issues.

// frontend
yarn run check
// frontend
yarn run fix

i18n

This project uses react-intl to manage the internationalisation. No user-facing messages should be hardcoded, there is a eslint rule throwing an error in such case.

Messages are all listed in a dedicated json file in the messages folder at the root of the project. Supporting multiple languages is about providing translations in the appropriate json files.

When running yarn run start or yarn run build the messages are automatically compiled under src/lib/lang. The compiled messages are the one used by the app

Usage

Use the hook useIntl which provides a set of functions such as formatMessage.

For messages, the id must be unique and following the naming convention <ComponentName>.<variableName>. The default message should always be set as it can be used as a fallback. It's also a good practice to give a description right away.

const SubmitButton = () => {
  const i18n = useIntl();

  const buttonLabel = i18n.formatMessage({
    id: "SubmitButton.buttonLabel",
    description: "Label of the Submit button",
    defaultMessage: "Submit",
  });

  return <button>{buttonLabel}</button>;
};

The message definition should always be copied into the json files in the messages folder (messages/en.json).

{
  "SubmitButton.buttonLabel": {
    "description": "Label of the Submit button",
    "defaultMessage": "Submit"
  }
}

You can run a dedicated script to extract all messages into the json file.

// frontend
yarn run messages:extract

See more information on the react-intl documentation.

Test

// frontend
yarn run test

Build

// frontend
yarn run build

Messages are compiled automatically before the build.

Note: The server part is currently written in javascript and doesn't require any build phase.

Deployment

Before building and deploying, set the environment variables according to your platform. See the required variables in .env.example. The variables NODE_ENV must be set to the value production for an optimised bundle. This is usually done by default on most platform.

The build command fo the frontend generates a build folder with the bundled static files of the frontend.

From there, several deployment options are possible.

  • Static files on a CDN or equivalent
  • Server + local static files
  • A mix of the above: server + static files a CDN location.

Static files

Note that this option prevents the meta tags from being dynamically updated before serving the page.

The build folder can be deployed to a CDN or equivalent (Netlify, Amplify, S3 web hosting, ..., heroku with the create-react-app buildpack fall in this options as well).

Server + local static files

This option allows dynamically setting the meta tags before serving the page.

Deploy the repository, build the frontend then run the server so that it serves the static files straight from the build folder.

The server has two entry points under the folder ./server/src:

  • servers.js for a server environment (EC2, Heroku with no particular buildpack, ...)
  • handler.js for a serverless environment (Lambda, ...), a serverless.yml is provided in the repository (although, in its current state it doesn't bundle the frontend build folder)

Note that a serverless deployment is not recommended with this option because all the static files will be requested through it, without the delivery optimisation that a CDN could provide. Check the next option.

Server + external static files

This option allows dynamically setting the meta tags before serving the page.

For this method to work, all the resources must be referenced with an absolute path, for instance https://cdn.verida.one/favicon.png instead of just /favicon.png. The environment variable PUBLIC_URL is use to that effect. CRA/Webpack prepends the variable to the path to the resources when building the frontend, so ensure to set this environment variable with the location where you will deploy the static files before building the frontend. After building, you can deploy on a CDN such as S3 + CloudFront.

The server, is deployed in a similar way as the previous option. The difference being it must be aware of the location of the resources. The environment variable RESOURCES_URL is used to determine if it should fetch the index.html locally or from the specified location. So do not forget to set the variable before running the server, for instance RESOURCES_URL=https://cdn.verida.one

Once again, the server has two entry points:

  • servers.js for a server environment (EC2, Heroku with no particular buildpack, ...)
  • handler.js for a serverless environment (Lambda, ...), a serverless.yml is provided in the repository

verida-one-webapp's People

Contributors

aurelticot avatar cmcwebcode40 avatar dependabot[bot] avatar tahpot avatar ysam21 avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

verida-one-webapp's Issues

Handle Collectible not found in UI

If a viewer ends up in the "Collectible Details" page (for instance via URL), but the collectible cannot be found, we currently display a blank page, while we should display some information for the user.

  • Get design
  • Implement it

Note that our resolution of the Collectible involves if the Collectible is allowed to be shown by configuration, ie: the wallet address owning the collectible shall be part of the configuration, this Collectible is not explicitly in the "hidden" list in the configuration.

It means that even if an NFT (defined by its chain, contract address and token id) actually exists, we can consider it as "non-displayable" / "not found"

Fix display chain logo in Collectible chip even with no price info

Currently if there is no information of price and price unit, the Chip is not displayed.
But there is the Chain logo on it, so it's relevant to keep it.

Will have to update the AssetPriceChip props to accept optional price and unit.

Questions are:

  • Should we display price if unit is missing
  • Should we display unit if price is missing

Also, considering the Chain logo is hidden in the compact variant, if the price and unit are not displayed (because missing), then the component should return null.

Fix the background image

According to the Figma design, only the Profile page has the gradient background, all other pages have a the solid background.

Implement Home page

The Home page is the default page when accessing the web app (top level url, no path to a profile or other pages).

There is no Figma design for this one yet.

Fix long Asset's description display

For the moment, the description in the Asset details pages are not truncated.
According to the design, it should be limited to 5 or 6 lines and if longer, display an ellipsis and a show more button to expand and reveal the full description.

While truncating the text to 5/6 lines is easy (with class line-clamp-x), knowing when to display a "show more" button and handling its behaviour is more challenging. It is possible with CSS only but will have to double check with Tailwind.

This ticket aims to address this.

Implement a fixed bottom bar

Several pages use a bottom bar to provide some actions, for instance: "View in Explorer" in the Collectibles details page.

This bottom bar is fixed at the bottom, the rest of the page scroll under it.

Note that the footer must not be covered by the bottom bar. It means footer should have a spacing of the height of the bottom bar below it.

As the footer is managed outside of the page defining if there's a bottom bar, it will be challenging.

We should investigate React Portals for that

Fetch Collectibles from Wallet Provider

Focused on the Collectibles (NFTs)

  • Get the list of public wallet addresses
  • Define API schemas and types
  • Update components and other utils using the updated types
  • Fetch data from Wallet Provider for theses addresses
  • Whatever the data strategy is (see #47 ), ensure the data is displayed in the corresponding pages
  • Remove collectibles from mock data

See #57 focused on personal information from Vault public profile
See #62 ,focused on the other data (links, wallets, ...)

Implement Search feature

A rough idea of the implementation is as follow:

  • A dedicated molecule component for the Search field
  • A dedicated molecule for the Search result item
  • A dedicated organism component for the Search Result
  • I'd say the Header integrates these component and manages the state but depending on the complexity it might good to move into a hook and dedicated components
  • The Search Result component will have to be positioned below the Search Field and accomodate the different designs on large and narrow screens. We'll have to look whether a position: fixed is enough or if a portal is needed.
  • The query being async, we should look at using useQuery
  • A debounce of the search query is likely needed
  • A loading state will be needed as well as an error state. If no design available, ask the design team
  • Clicking on a search result item will redirect to the profile page and clear the state of the search

Handle Badge not found in UI

If a viewer ends up in the "Badge Details" page (for instance via URL), but the badge cannot be found, we currently display a blank page, while we should display some information for the user.

  • Get design
  • Implement it

Note that our resolution of the badge involves if the badge is allowed to be shown by configuration, ie: the wallet address owning the badge shall be part of the configuration, this badge is not explicitly in the "hidden" list in the configuration.

It means that even if an SBT (defined by its chain, contract address and token id) actually exists, we can consider it as "non-displayable" / "not found"

Fetch personal information from Vault public profile

Focused on the Verida public profile information (name, avatar, bio)

  • Fetch data from the Verida Network (Vault public profile)
  • Whatever the data strategy is (see #47 ), ensure the data is displayed in the Profile page

See #62 ,focused on the other data (links, wallets, ...)
See #58 ,focused on on-chain assets (NFTs and SBTs)

Handle empty list in the Badge List page

If a viewer ends up in the "Badge List" page (for instance via URL), but the list is empty, we currently display a blank page, while we should display some information for the user.

  • Get design for empty list
  • Implement it

Implement Verida React context, helpers and hook

Create a VeridaContext to handle connect, disconnect, access to Verida context, profile, etc.
If needed create a helper for the Verida operations.
Create a hook to simplify getting the React context.

Define `title` property on some elements (tooltip)

The title property on html tags allow displaying a sam textual tooltip while hovering on it.

List of element to add some information:

  • Verida tick icon -> "Verified by Verida"
  • Any blockchain logo -> The blockchain name, ie: "Ethereum", "Polygon", ...
  • Social Media link -> Platform and id, ie: "@Thapot on Twitter", ...
  • Wallet address -> the full address, as the rendered could be truncated
  • Most icon buttons and icon links (as they have no label) -> what it does, where it goes, ie: "Copy to clipboard", "Open in explorer"
  • ...

Feel free to extend

Implement "Share" modal

We should explore React Portal to achieve it.

I see the following structure (not exhaustive).

  • Modal component (molecule)
    • defining style and behaviour (responsive) of the modal
    • Defined as a Portal targeting an element high in the DOM
  • ShareModalcomponent (organism)
    • Using Modal as a container
    • Defining the content of the modal
  • In whatever component the ShareModal must be displayed, place it in render tree and managed its visibility state and other props.

Consider using the Web Share API for the Share button

Handle empty profile display

For a valid identity (Verida name or DID can be resolved), if the user haven't configured its Verida One profile, or if the configuration is empty, the UI should display an information message to the viewer.

See Figma design

Fetch information from Verida One configuration datastore

Focused on the Verida One specific data (links, wallets, social media, ...)

  • Create a environment variable for the schema URL
  • Fetch data from the Verida Network (Verida One Configuration datastore)
  • Whatever the data strategy is (see #47 ), ensure the data is displayed in the corresponding pages

See #57 focused on personal information from Vault public profile
See #58 ,focused on on-chain assets (NFTs and SBTs)

URL of the Verida One profile schema:
https://common.schemas.verida.io/veridaOne/profile/latest/schema.json

Optimise for SEO

Including (not exhaustive):

  • meta tag
  • social graph
  • profile image for search engine and other URL rendering

Implement 'Not Found' profile page

If arriving on the webapp with a url that cannot be resolved. We should display a dedicated page informing the user and suggesting some actions.

  • Get design from Excited
  • Implement the page
  • Set up the router to redirect to this page

Update Tailwind config

  • Allow a spacing of 2.75
  • Define additional text options (our custom typography doesn't fit the default tailwind font-size and line-height)
  • ...

Consider lazy loading and code splitting

If loading performance is an issue and it is necessary to reduce the size of the bundle, we should consider code splitting.

Main pages can be set as lazy loading as well as some other components such as modals.

Implement tooltips

  • At least use the title property

Then when time:

  • Create a tooltip component
  • Add the tooltip where needed

Handle empty list in the Collectible List page

If a viewer ends up in the "Collectible List" page (for instance via URL), but the list is empty, we currently display a blank page, while we should display some information for the user.

  • Get design for empty list
  • Implement it

Define unit tests

Set up the unit testing structure and start writing unit tests for components.

Consider Storybook for defining the tests, see #20

Fix internal links and non-reset of the scroll

When using useNavigate from react-router on a Button, we loose some behaviour of a normal link, for instance the "Open link in new Tab" in the contextual menu (or often shortcut middle-click).

Additionally, and more importantly, it looks like the scroll is not reset when moving to another page.
For example: Scrolling down on the Profile page to the "Collectibles" section and clicking on the "Show all" will redirect us to the "Collectibles" page but the scroll is still in the middle of the page.

It looks like using the <Link /> from react-router is more appropriate than the navigate(...).

We should update the <ButtonLinkBase/> to be either internal or external and use either Link or a.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.