136 Commits

Author SHA1 Message Date
Daria Golova
9686e5245f changed userData to accounData 2022-08-03 11:14:47 +03:00
Daria Golova
1f306b2dce Merge pull request #52 from franze6/DID-11
added data check for the table on Profile page
2022-08-03 10:31:48 +03:00
Daria Golova
0e5d7477fc added data check for the table on Profile page 2022-08-02 20:57:10 +03:00
kandrusyak
f395661480 some fixes 2022-08-02 19:11:05 +03:00
kandrusyak
4c334648cb remove links 2022-08-02 18:55:04 +03:00
kandrusyak
344b2c7862 add proxy api 2022-08-01 14:07:23 +03:00
Daria Golova
826f340e9a Merge pull request #51 from franze6/DID-11
added the seed field in the store
2022-07-27 16:24:54 +03:00
Daria Golova
b4bccf2cba added the seed field in the store 2022-07-27 16:20:33 +03:00
Daria Golova
7bb1832d4d added the seed field in the store 2022-07-27 15:58:15 +03:00
Daria Golova
17ac1b04eb Merge pull request #50 from franze6/DID-11
removed the scroll from the input
2022-07-27 15:39:32 +03:00
Daria Golova
e4dc1e961e removed the scroll from the input 2022-07-27 15:39:05 +03:00
Daria Golova
fa198054dd Merge pull request #49 from franze6/DID-11
fixed a bug when deleting elements
2022-07-27 14:31:31 +03:00
Daria Golova
f31c895b8d fixed a bug when deleting elements 2022-07-27 14:28:11 +03:00
Daria Golova
b7be78cf76 Merge pull request #48 from franze6/DID-12
fixed function references
2022-07-26 17:42:56 +03:00
Daria Golova
6d92fde547 fixed function references 2022-07-26 17:39:42 +03:00
DuCay
03bc841894 Merge pull request #47 from franze6/DID-12
Change page signin
2022-07-26 17:18:20 +03:00
DuCay
c24a1fa09d Merge branch 'master' into DID-12 2022-07-26 17:18:14 +03:00
DwCay
57e5dee442 Change page signin 2022-07-26 17:00:39 +03:00
Daria Golova
188e79caf9 Merge pull request #46 from franze6/DID-11
replaced forms with divs and old logo
2022-07-26 14:10:53 +03:00
Daria Golova
e9b21c5c02 replaced forms with divs and old logo 2022-07-26 14:09:48 +03:00
DuCay
75464d81f0 Merge pull request #45 from franze6/DID-12
Did 12
2022-07-26 11:42:10 +03:00
DwCay
fcb7d40ca5 Add method get and save passPhrase. Сorrections in the display of data on the page validationLog 2022-07-26 03:33:11 +03:00
DwCay
f27edb97bb Change methods for new transactions data 2022-07-25 17:55:34 +03:00
Daria Golova
b75a2349c2 Merge pull request #44 from franze6/DID-11
removed the verification of the updating form
2022-07-25 16:47:38 +03:00
Daria Golova
37c9feffe1 removed the verification of the updating form 2022-07-25 16:46:35 +03:00
Daria Golova
fe6bcf8d0f Merge pull request #43 from franze6/DID-11
Добавила проверку заполнения формы изменения параметров профиля
2022-07-21 16:15:02 +03:00
Daria Golova
d7488f8ca9 deleted an extra line 2022-07-21 16:12:23 +03:00
Daria Golova
ffa92ded10 deleted console.log 2022-07-21 16:09:44 +03:00
Daria Golova
68e94201e0 added an update form check 2022-07-21 16:07:40 +03:00
DuCay
020e45ddce Merge pull request #42 from franze6/DID-10
Change fetch Node info data for POST methods
2022-07-21 11:39:37 +03:00
DwCay
8955d846e4 Change fetch Node info data for POST methods 2022-07-21 11:39:07 +03:00
DuCay
d5bc90c818 Merge pull request #41 from franze6/DID-10
Bug fixes when trying to get data on page reload
2022-07-19 23:11:15 +03:00
DuCay
16a2ffca2d Merge branch 'master' into DID-10 2022-07-19 23:11:07 +03:00
DwCay
f932c0bc33 Bug fixes when trying to get data on page reload 2022-07-19 23:09:47 +03:00
Daria Golova
da268d7ecc Merge pull request #40 from franze6/DID-11
Проверка кода, ренейминг
2022-07-18 15:16:30 +03:00
Daria Golova
736e8fc16b deleted settings.json 2022-07-18 15:14:43 +03:00
Daria Golova
774955f131 code review 2022-07-18 15:11:20 +03:00
DuCay
5b20d71a0c Merge pull request #39 from franze6/DID-10
Did 10
2022-07-18 11:31:49 +03:00
DuCay
9714b0add8 Merge branch 'master' into DID-10 2022-07-18 11:31:43 +03:00
DwCay
52eb2a75c1 Fix onBecomeObserved reaction property 2022-07-18 11:27:55 +03:00
DwCay
3c77264fae Fix url 2022-07-18 11:16:02 +03:00
DwCay
429f36b6a6 Refactoring store and association stores into one 2022-07-15 18:54:03 +03:00
Daria Golova
11be69a79b Merge pull request #38 from franze6/DID-9
Исправила url, настроила дефолтный шрифт
2022-07-15 17:26:38 +03:00
Daria Golova
911c13cb87 fixed url, font 2022-07-15 17:22:34 +03:00
kandrusyak
1e9830c8d4 fix merge 2022-07-15 12:10:06 +03:00
Kirill Andrusyak
a8a6355daa Merge pull request #37 from franze6/DID-9
Интеграция страницы Verify с сервером
2022-07-15 12:09:26 +03:00
Kirill Andrusyak
444c94690b Merge branch 'master' into DID-9 2022-07-15 12:09:19 +03:00
Kirill Andrusyak
67133c5414 Merge pull request #36 from franze6/DID-8
Интеграция страницы ValidationLog с сервером
2022-07-15 11:52:25 +03:00
Kirill Andrusyak
f58a94bf24 Merge pull request #35 from franze6/DID-7
Внесла правки на странице Profile
2022-07-15 11:51:01 +03:00
DwCay
9820692cd9 Добавлен адресс аккаунта совершившего транзакцию 2022-07-13 15:39:20 +03:00
Daria Golova
2eeb39abc9 rendered the data in the component 2022-07-13 14:45:17 +03:00
DwCay
5eb4ee16c0 Удален ValidationLogStore 2022-07-13 14:31:27 +03:00
DwCay
bc364d1b85 Исправлен нейминг в store и transactionsStore. Возвращены иконки юзеров на страницу ValidationLog 2022-07-13 14:30:11 +03:00
DwCay
8489bc375c Интеграция страницы ValidationLog с сервером 2022-07-12 19:21:39 +03:00
Daria Golova
b9f795c0e4 done store for shared data 2022-07-12 16:56:44 +03:00
Daria Golova
47dfcf347c added stacking context for the hint 2022-07-11 15:08:45 +03:00
Daria Golova
e837f7cc89 added onblur, fixed seed, moved default values 2022-07-11 15:08:45 +03:00
DuCay
7ad29e8fe0 Merge pull request #34 from franze6/DID-6
Refactoring method saveDataRegistration in store
2022-07-11 11:16:42 +03:00
DwCay
0fb5764a70 Refactoring method saveDataRegistration in store 2022-07-11 11:15:53 +03:00
DuCay
5ebc965a2a Merge pull request #33 from franze6/DID-6
Refactoring in Onboarding steps
2022-07-08 21:24:21 +03:00
DuCay
138047fa10 Merge branch 'master' into DID-6 2022-07-08 21:24:04 +03:00
DwCay
a271da7bf9 Refactoring in Onboarding steps 2022-07-08 21:20:09 +03:00
Kirill Andrusyak
79784cbcee Merge pull request #32 from franze6/DID-7
Создана форма изменения параметров профиля, добавлен функционал для изменения и добавления параметров
2022-07-08 16:32:18 +03:00
Daria Golova
596c44aac3 changed strange IIFE function 2022-07-07 10:19:31 +03:00
Daria Golova
5d17137815 made sending data 2022-07-06 20:22:48 +03:00
Daria Golova
18bf373508 changed the names of the methods 2022-07-06 19:38:09 +03:00
Daria Golova
944c9989e9 fix seed 2022-07-06 19:33:27 +03:00
Daria Golova
202989f374 agreed on form to change and add 2022-07-06 19:33:27 +03:00
Daria Golova
f21d10f830 added prop key, made update form 2022-07-06 19:33:27 +03:00
DuCay
c8604a56ac Merge pull request #31 from franze6/DID-6
Changing data in store to array
2022-07-06 19:27:56 +03:00
DwCay
2d0ae35cc8 Changing data in store to array 2022-07-06 19:27:26 +03:00
DuCay
76f942b90f Merge pull request #30 from franze6/DID-6
Change methods in store
2022-07-06 18:52:22 +03:00
DwCay
f0e0d9479d Change methods in store 2022-07-06 18:51:57 +03:00
DuCay
3403289e0a Merge pull request #29 from franze6/DID-6
New naming for store
2022-07-06 12:59:44 +03:00
DwCay
25fddec6e8 New naming for store 2022-07-06 12:58:53 +03:00
DuCay
1d0cb45024 Merge pull request #28 from franze6/DID-6
Fix naming in store
2022-07-06 12:46:06 +03:00
DwCay
222850dfd9 Fix naming in store 2022-07-06 12:44:53 +03:00
Kirill Andrusyak
8f225752cf Merge pull request #27 from franze6/DID-6
Add method for delete property account
2022-07-06 12:28:46 +03:00
kandrusyak
038657751a add deploy files 2022-07-05 15:18:36 +03:00
kandrusyak
29d7d6fdb8 change endpoint url 2022-07-05 15:12:22 +03:00
DwCay
e44dfee284 Add method for delete property account 2022-07-04 18:02:34 +03:00
Kirill Andrusyak
0f455f126d Merge pull request #26 from franze6/DID-5
Интеграция таблицы страницы Profile с сервером
2022-07-04 10:10:03 +03:00
Daria Golova
0d4f27660a Merge branch 'DID-5' 2022-07-01 17:27:39 +03:00
Daria Golova
9703371f28 made a reference book 2022-07-01 17:16:09 +03:00
Daria Golova
16ca8a1df2 converted user data into Map object 2022-07-01 16:03:21 +03:00
Daria Golova
e883b190a7 converted user data into Map object 2022-07-01 16:01:20 +03:00
Daria Golova
85897a8efe changed name of the method in store.js 2022-06-30 14:50:59 +03:00
Daria Golova
5f85d1696a integrated received data into table 2022-06-30 14:42:59 +03:00
Daria Golova
1c539e5255 made userDataStore 2022-06-30 14:42:59 +03:00
DuCay
bcfc018560 Merge pull request #25 from franze6/DID-4
Did 4
2022-06-30 13:35:58 +03:00
DwCay
e175ca0295 fix naming for post method 2022-06-30 13:35:07 +03:00
DwCay
bac246eac2 fix label name for post request 2022-06-30 13:17:10 +03:00
DwCay
f65c99e86a fix store 2022-06-29 19:35:06 +03:00
DwCay
63439b2da1 Add method post encrypt auth data 2022-06-29 18:47:49 +03:00
Kirill Andrusyak
1d9368d200 Merge pull request #24 from franze6/DID-3
Доработка формы создания поля
2022-06-28 17:01:22 +03:00
kandrusyak
3a4ed9daf9 auth 2022-06-28 16:38:05 +03:00
Daria Golova
54ccd3ed9f fix popup hint 2022-06-23 18:52:19 +03:00
Daria Golova
fe1105e9d6 delete useEffect 2022-06-23 15:28:29 +03:00
Daria Golova
95cc2ac1e0 fix property field, added default value of seed 2022-06-23 15:21:08 +03:00
Daria Golova
b4516ef18e made a popup hint 2022-06-22 19:36:58 +03:00
kandrusyak
d617de75b5 router fix 2022-06-22 14:53:31 +03:00
Kirill Andrusyak
83e5e39d3c Merge pull request #21 from franze6/DID-2
Создание fetch wrapper
2022-06-21 11:47:58 +03:00
Kirill Andrusyak
f89d59e7df Merge branch 'master' into DID-2 2022-06-21 11:47:49 +03:00
Kirill Andrusyak
c944644db0 Merge pull request #23 from franze6/DID-1
Did 1
2022-06-21 11:44:57 +03:00
DwCay
bfdddee46a Add method for get passPhrase and generation hex for account logo 2022-06-18 16:50:32 +03:00
kandrusyak
0da68ddd63 migrate to webpack 2022-06-17 16:56:30 +03:00
Daria Golova
f209ee5f5f added token availability check 2022-06-16 16:05:48 +03:00
Daria Golova
9bef3d9311 fix authorization by token 2022-06-16 15:25:25 +03:00
Daria Golova
632b98a81a added authorization by token 2022-06-16 14:30:41 +03:00
DwCay
eeaabeebf3 Add method for get passPhrase 2022-06-15 17:41:02 +03:00
Daria Golova
81f5ec2741 fix methods 2022-06-15 14:36:23 +03:00
Daria Golova
3fcda54070 fix wrapper 2022-06-15 14:21:39 +03:00
Daria Golova
49aff14a80 create fetch wrapper 2022-06-14 13:53:28 +03:00
DwCay
da04efbf80 Add registration store 2022-06-14 13:13:58 +03:00
DuCay
541c5988e9 Merge pull request #20 from franze6/Deleting_elements
Delete Onboarding and Component from Sidebar
2022-06-02 15:53:43 +03:00
DwCay
cfa5af78c0 Delete Onboarding and Component from Sidebar 2022-06-02 15:53:06 +03:00
DuCay
fc4d9fb897 Merge pull request #19 from franze6/Validation_merged
Update Validate Panel
2022-06-02 15:35:15 +03:00
DwCay
ed5565eb17 Update Validate Panel 2022-06-02 15:34:20 +03:00
DuCay
99512491fa Merge pull request #18 from franze6/Onboarding_steps
Start window Onboarding1
2022-06-02 14:40:24 +03:00
DwCay
24a66478d6 Start window Onboarding1 2022-06-02 14:27:04 +03:00
DuCay
9484b0bda9 Merge pull request #17 from franze6/Validation_merged
Fix errors and styling
2022-06-01 20:46:49 +03:00
DwCay
885963be45 Fix errors and styling 2022-06-01 20:45:14 +03:00
DuCay
e144e50a40 Merge pull request #16 from franze6/Onboarding_steps
Fix routing link in onboarding steps
2022-06-01 17:59:40 +03:00
DwCay
16f9a52a41 Fix routing link in onboarding steps 2022-06-01 17:58:51 +03:00
DuCay
5e74f2bc0b Merge pull request #15 from franze6/Onboarding_steps
Onboarding fix styling
2022-06-01 17:36:25 +03:00
DuCay
fa5ddbf64a Merge branch 'master' into Onboarding_steps 2022-06-01 17:36:15 +03:00
DwCay
c45b7c5e4d Onboarding fix styling 2022-06-01 17:33:20 +03:00
Daria Golova
606223216f Merge pull request #13 from franze6/Profile-Page
fix profile page
2022-06-01 17:25:45 +03:00
Daria Golova
c41bed05fd Merge pull request #14 from franze6/Verify-Page
fix verify page
2022-06-01 17:25:34 +03:00
Daria Golova
b71dccbd0e fix field on sidepanel 2022-06-01 17:18:22 +03:00
Daria Golova
264a908352 fix paddings 2022-06-01 16:51:32 +03:00
Daria Golova
36eb756be0 fix key 2022-06-01 16:21:14 +03:00
DuCay
f74293b1f4 Merge pull request #12 from franze6/Onboarding_steps
Onboarding2 fix name for form
2022-06-01 15:57:57 +03:00
DwCay
095c5e236e Onboarding2 fix name for form 2022-06-01 15:56:09 +03:00
DuCay
f3dcbdab49 Merge pull request #11 from franze6/Shared_data_
Shared data
2022-06-01 14:45:05 +03:00
Kirill Andrusyak
568543bba5 Merge pull request #10 from franze6/Deleting_elements 2022-06-01 00:50:02 +03:00
48 changed files with 13573 additions and 2378 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
# dependencies
/node_modules
/node_modules
.idea

15
Dockerfile Normal file
View File

@@ -0,0 +1,15 @@
FROM node:16-alpine AS builder
WORKDIR /front
COPY . .
RUN npm install
RUN npm run build
FROM nginx:1.21.6-alpine as runner
COPY ./deploy/nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /front/build /var/www/html
EXPOSE 8080

View File

@@ -1,26 +0,0 @@
# Mosaic React
React landing page template designed by Cruip.
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run dev
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://vitejs.dev/guide/).
## Support notes
We are shipping our templates with a very basic React configuration to let you quickly get into the development process, but we don't discourage you from using any other configuration or framework built on the top of React. So, please note that any request dealing with React (e.g. extra features, customisations, et cetera) is to be considered out of the support scope.
For more information about what support covers, please see our (FAQs)[https://cruip.com/faq/].

33
deploy/nginx.conf Normal file
View File

@@ -0,0 +1,33 @@
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
gzip_static on;
server {
listen 8080;
server_name localhost;
charset utf-8;
location / {
root /var/www/html;
try_files $uri /index.html;
etag on;
expires max;
add_header Cache-Control public;
location = /index.html {
expires 0;
add_header Cache-Control "no-cache, public, must-revalidate, proxy-revalidate";
}
}
}
}

View File

@@ -1,21 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body class="font-inter antialiased bg-slate-100 text-slate-600">
<noscript>You need to enable JavaScript to run this app.</noscript>
<script>
if (localStorage.getItem('sidebar-expanded') == 'true') {
document.querySelector('body').classList.add('sidebar-expanded');
} else {
document.querySelector('body').classList.remove('sidebar-expanded');
}
</script>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>

13297
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,27 +2,60 @@
"name": "mosaic-react",
"version": "0.1.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
"dev": "webpack-dev-server",
"build": "webpack"
},
"dependencies": {
"@liskhq/lisk-client": "^5.2.2",
"@tailwindcss/forms": "^0.4.0",
"autoprefixer": "^10.4.5",
"buffer": "^6.0.3",
"chart.js": "^3.5.0",
"chartjs-adapter-moment": "^1.0.0",
"crypto-browserify": "^3.12.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"mobx": "^6.6.0",
"mobx-react-lite": "^3.4.0",
"moment": "^2.29.1",
"net": "^1.0.2",
"os-browserify": "^0.3.0",
"path-browserify": "^1.0.1",
"postcss-loader": "^7.0.0",
"process": "^0.11.10",
"querystring-es3": "^0.2.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-flatpickr": "^3.10.7",
"react-router-dom": "^6.2.1",
"react-transition-group": "^4.4.1"
"react-transition-group": "^4.4.1",
"stream-browserify": "^3.0.0",
"url": "^0.11.0",
"util": "^0.12.4"
},
"devDependencies": {
"@vitejs/plugin-react": "^1.0.7",
"autoprefixer": "^10.4.2",
"@babel/core": "^7.18.5",
"@babel/preset-env": "^7.18.2",
"@babel/preset-react": "^7.17.12",
"babel-loader": "^8.2.5",
"css-loader": "^6.7.1",
"html-loader": "^3.1.2",
"postcss": "^8.4.5",
"sass": "^1.49.0",
"sass": "^1.52.3",
"sass-loader": "^13.0.0",
"style-loader": "^3.3.1",
"tailwindcss": "^3.0.18",
"vite": "^2.7.2"
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.9.2"
},
"babel": {
"presets": [
"@babel/env",
"@babel/react"
]
},
"browser": {
"fs": false
}
}

View File

@@ -1,7 +1,7 @@
import tailwind from 'tailwindcss'
import autoprefixer from 'autoprefixer'
import tailwindConfig from './src/css/tailwind.config.js'
const tailwind = require('tailwindcss')
const autoprefixer = require('autoprefixer')
const tailwindConfig = require('./src/tailwind.config.js')
export default {
module.exports = {
plugins: [tailwind(tailwindConfig), autoprefixer],
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

11
public/index.html Normal file
View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
import {
Routes,
Route,
useLocation
useLocation,
} from 'react-router-dom';
import './css/style.scss';
@@ -27,12 +27,14 @@ import Onboarding3 from "./pages/Onboarding3";
import Onboarding4 from "./pages/Onboarding4";
import SharedData from "./pages/SharedData";
import ResetPassword from "./pages/ResetPassword";
import Signup from "./pages/Signup";
import Signin from "./pages/Signin";
import SignIn from "./pages/SignIn";
function App() {
const location = useLocation();
useEffect(()=> {
localStorage.setItem('svgAvatar', '')
},[])
useEffect(() => {
document.querySelector('html').style.scrollBehavior = 'auto'
@@ -43,7 +45,8 @@ function App() {
return (
<>
<Routes>
<Route exact path="/" element={<Dashboard />} />
<Route exact path="/" element={<Onboarding1 />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/dashboard/analytics" element={<Analytics />} />
<Route path="/dashboard/fintech" element={<Fintech />} />
<Route path="/digitalId/profile-id" element={<ProfileId />} />
@@ -51,7 +54,6 @@ function App() {
<Route path="/digitalId/validation-log" element={<ValidationLog />} />
<Route path="/digitalId/verify" element={<Verify />} />
<Route path="/messages" element={<Messages />} />
<Route path="/onboarding-1" element={<Onboarding1 />} />
<Route path="/onboarding-2" element={<Onboarding2 />} />
<Route path="/onboarding-3" element={<Onboarding3 />} />
<Route path="/onboarding-4" element={<Onboarding4 />} />
@@ -60,8 +62,7 @@ function App() {
<Route path="/component/badge" element={<BadgePage />} />
<Route path="/component/accordion" element={<AccordionPage />} />
<Route path="/reset-password" element={<ResetPassword />} />
<Route path="/signin" element={<Signin />} />
<Route path="/signup" element={<Signup />} />
<Route path="/signIn" element={<SignIn />} />
</Routes>
</>
);

3
src/api/node.js Normal file
View File

@@ -0,0 +1,3 @@
import {fetchWrapper} from '../shared/fetchWrapper';
export const getNodeInfo = (headers) => fetchWrapper.get('node/info/', headers)

View File

@@ -1,12 +1,14 @@
import React, { useState, useRef, useEffect } from 'react';
import {observer} from "mobx-react-lite";
import { Link } from 'react-router-dom';
import Transition from '../utils/Transition';
import {registrationStore} from "../store/store";
import {generateSvgAvatar} from "../images/GenerateOnboardingSvg/GenerateSvg";
import UserAvatar from '../images/user-avatar-32.png';
function DropdownProfile({
const DropdownProfile = observer(({
align
}) {
})=>{
const [dropdownOpen, setDropdownOpen] = useState(false);
@@ -43,7 +45,7 @@ function DropdownProfile({
onClick={() => setDropdownOpen(!dropdownOpen)}
aria-expanded={dropdownOpen}
>
<img className="w-8 h-8 rounded-full" src={localStorage.getItem('svgAvatar') || UserAvatar} width="32" height="32" alt="User" />
<img className="w-8 h-8 rounded-full" src={generateSvgAvatar(registrationStore.pubKey) || UserAvatar} width="32" height="32" alt="User" />
<div className="flex items-center truncate">
<span className="truncate ml-2 text-sm font-medium group-hover:text-slate-800">Acme Inc.</span>
<svg className="w-3 h-3 shrink-0 ml-1 fill-current text-slate-400" viewBox="0 0 12 12">
@@ -75,7 +77,7 @@ function DropdownProfile({
<li>
<Link
className="font-medium text-sm text-indigo-500 hover:text-indigo-600 flex items-center py-1 px-3"
to="/"
to="/dashboard"
onClick={() => setDropdownOpen(!dropdownOpen)}
>
Settings
@@ -84,7 +86,7 @@ function DropdownProfile({
<li>
<Link
className="font-medium text-sm text-indigo-500 hover:text-indigo-600 flex items-center py-1 px-3"
to="/"
to="/dashboard"
onClick={() => setDropdownOpen(!dropdownOpen)}
>
Sign Out
@@ -95,6 +97,6 @@ function DropdownProfile({
</Transition>
</div>
)
}
})
export default DropdownProfile;

View File

@@ -3,7 +3,6 @@
@tailwind base;
@tailwind components;
// Additional styles
@import 'additional-styles/utility-patterns.scss';
@import 'additional-styles/range-slider.scss';
@import 'additional-styles/toggle-switch.scss';

View File

@@ -35,13 +35,10 @@ function createBlob(options) {
return path + "z";
}
export var generateSvgAvatar = (function () {
return function (seed, raw) {
let pubKey = localStorage.getItem('svgKey') || Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16);
export var generateSvgAvatar = ( function () {
return function (publicKey, seed, raw) {
let pubKey = publicKey || Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16) + Math.floor(Math.random()*65535*65535).toString(16);
//pubKey = "73f47d4929d7b2b6598ca4999d52567f9bb5aef3e353e0a66b468096db6e4e88"
if (!localStorage.getItem('svgKey')) {
localStorage.setItem('svgKey', `${pubKey}`)
}
let particles = [];
let gradients = ['#000000'];
let defs = [];

View File

@@ -1,8 +1,11 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router } from 'react-router-dom'
import {Buffer} from "buffer";
import { HashRouter as Router } from 'react-router-dom'
import App from './App'
globalThis.Buffer = Buffer
ReactDOM.render(
<React.StrictMode>
<Router>
@@ -10,4 +13,4 @@ ReactDOM.render(
</Router>
</React.StrictMode>,
document.getElementById('root')
)
)

View File

@@ -1,4 +1,4 @@
import React, {useEffect, useState} from 'react';
import React, {useState} from 'react';
import Sidebar from '../partials/Sidebar';
import Header from '../partials/Header';
@@ -19,9 +19,6 @@ import DashboardCard10 from '../partials/dashboard/DashboardCard10';
import DashboardCard11 from '../partials/dashboard/DashboardCard11';
function Dashboard() {
useEffect(() => {
localStorage.setItem('svgKey', '')
}, [])
const [sidebarOpen, setSidebarOpen] = useState(false);
return (

View File

@@ -1,11 +1,17 @@
import React from 'react';
import React, {useEffect} from 'react';
import { Link } from 'react-router-dom';
import OnboardingImage from '../images/onboarding-image.jpg';
import OnboardingDecoration from '../images/auth-decoration.png';
import Logo from "../images/logo.png";
import { observer } from "mobx-react-lite";
import { registrationStore } from "../store/store";
const Onboarding1 = observer(() => {
useEffect(()=>{
registrationStore.generatePassPhrase()
}, [])
function Onboarding1() {
return (
<main className="bg-white">
@@ -21,31 +27,31 @@ function Onboarding1() {
{/* Header */}
<div className="flex items-center justify-between h-16 px-4 sm:px-6 lg:px-8">
{/* Logo */}
<Link className="block" to="/">
<Link className="block" to="/dashboard">
<img alt='logo' src={Logo} width="89" height="32"/>
</Link>
<div className="text-sm">
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signin">Sign In</Link>
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signIn">Sign In</Link>
</div>
</div>
{/* Progress bar */}
<div className="px-4 pt-12 pb-8">
<div className="px-4 pt-12 pb-[142px]">
<div className="max-w-md mx-auto w-full">
<div className="relative">
<div className="absolute left-0 top-1/2 -mt-px w-full h-0.5 bg-slate-200" aria-hidden="true"></div>
<ul className="relative flex justify-between w-full">
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-1">1</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/">1</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-2">2</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-2">2</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-3">3</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-3">3</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-4">4</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-4">4</span>
</li>
</ul>
</div>
@@ -56,9 +62,9 @@ function Onboarding1() {
<div className="px-4 py-8">
<div className="max-w-md mx-auto">
<h1 className="text-3xl text-slate-800 font-bold mb-6">Tell us about your company </h1>
<h1 className="text-3xl text-slate-800 font-bold mb-12">Tell us about your company </h1>
{/* Form */}
<form>
<div>
<div className="sm:flex space-y-3 sm:space-y-0 sm:space-x-4 mb-8">
<label className="flex-1 relative block cursor-pointer">
<input type="radio" name="radio-buttons" className="peer sr-only" defaultChecked />
@@ -67,7 +73,7 @@ function Onboarding1() {
<circle className="text-indigo-100" cx="20" cy="20" r="20" />
<path className="text-indigo-500" d="m26.371 23.749-3.742-1.5a1 1 0 0 1-.629-.926v-.878A3.982 3.982 0 0 0 24 17v-1.828A4.087 4.087 0 0 0 20 11a4.087 4.087 0 0 0-4 4.172V17a3.982 3.982 0 0 0 2 3.445v.878a1 1 0 0 1-.629.928l-3.742 1.5a1 1 0 0 0-.629.926V27a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.323a1 1 0 0 0-.629-.928Z" />
</svg>
<div className="font-medium text-slate-800 mb-1">Individual</div>
<div className="font-semibold text-slate-800 mb-1">Individual</div>
<div className="text-sm">Lorem ipsum is place text commonly used.</div>
</div>
<div className="absolute inset-0 border-2 border-transparent peer-checked:border-indigo-400 rounded pointer-events-none" aria-hidden="true"></div>
@@ -82,7 +88,7 @@ function Onboarding1() {
<path className="text-indigo-300" d="m30.377 22.749-3.709-1.5a1 1 0 0 1-.623-.926v-.878A3.989 3.989 0 0 0 28.027 16v-1.828c.047-2.257-1.728-4.124-3.964-4.172-2.236.048-4.011 1.915-3.964 4.172V16a3.989 3.989 0 0 0 1.982 3.445v.878a1 1 0 0 1-.623.928c-.906.266-1.626.557-2.159.872-.533.315-1.3 1.272-2.299 2.872 1.131.453 6.075-.546 6.072.682V28a2.99 2.99 0 0 1-.182 1h7.119A.996.996 0 0 0 31 28v-4.323a1 1 0 0 0-.623-.928Z" />
<path className="text-indigo-500" d="m22.371 24.749-3.742-1.5a1 1 0 0 1-.629-.926v-.878A3.982 3.982 0 0 0 20 18v-1.828A4.087 4.087 0 0 0 16 12a4.087 4.087 0 0 0-4 4.172V18a3.982 3.982 0 0 0 2 3.445v.878a1 1 0 0 1-.629.928l-3.742 1.5a1 1 0 0 0-.629.926V28a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.323a1 1 0 0 0-.629-.928Z" />
</svg>
<div className="font-medium text-slate-800 mb-1">Organization</div>
<div className="font-semibold text-slate-800 mb-1">Organization</div>
<div className="text-sm">Lorem ipsum is place text commonly used.</div>
</div>
<div className="absolute inset-0 border-2 border-transparent peer-checked:border-indigo-400 rounded pointer-events-none" aria-hidden="true"></div>
@@ -91,7 +97,7 @@ function Onboarding1() {
<div className="flex items-center justify-between space-x-6 mb-8">
<div>
<div className="font-medium text-slate-800 text-sm mb-1">💸 Lorem ipsum is place text commonly?</div>
<div className="text-xs">Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts.</div>
<div className="text-xs font-normal leading-6">Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts.</div>
</div>
<div className="flex items-center">
<div className="form-switch">
@@ -104,9 +110,11 @@ function Onboarding1() {
</div>
</div>
<div className="flex items-center justify-between">
<Link className="btn bg-indigo-500 hover:bg-indigo-600 text-white ml-auto" to="/onboarding-2">Next Step -&gt;</Link>
<button className="font-medium btn bg-indigo-500 hover:bg-indigo-600 text-white ml-auto">
<Link to="/onboarding-2">Next Step -&gt;</Link>
</button>
</div>
</form>
</div>
</div>
</div>
@@ -125,6 +133,6 @@ function Onboarding1() {
</main>
);
}
})
export default Onboarding1;

View File

@@ -1,11 +1,47 @@
import React from 'react';
import React, {useState} from 'react';
import { Link } from 'react-router-dom';
import { observer } from "mobx-react-lite";
import { registrationStore } from "../store/store";
import OnboardingImage from '../images/onboarding-image.jpg';
import OnboardingDecoration from '../images/auth-decoration.png';
import Logo from "../images/logo.png";
function Onboarding2() {
const Onboarding2 = observer(() => {
const [dataRegistration, setDataRegistration] = useState(
{
firstname: '',
secondname: '',
gender: '',
birthdate: '',
}
);
const [fillingForm, setFillingForm] = useState(false);
const saveValueChange = (event) => {
const newValue=event.target.value;
setDataRegistration({
...dataRegistration,
[event.target.id]: newValue,
})
};
const checkFillingForm = () => {
if (!Object.keys(dataRegistration).find(item => !dataRegistration[item])) {
setFillingForm(true);
}
};
const saveStoreRegistration = () => {
if (fillingForm) {
registrationStore.saveDataRegistration(Object.keys(dataRegistration).map(item => {
return{
key: `${item}`,
value: dataRegistration[item],
}
}))
}
};
return (
<main className="bg-white">
@@ -21,31 +57,31 @@ function Onboarding2() {
{/* Header */}
<div className="flex items-center justify-between h-16 px-4 sm:px-6 lg:px-8">
{/* Logo */}
<Link className="block" to="/">
<Link className="block" to="/dashboard">
<img alt='logo' src={Logo} width="89" height="32"/>
</Link>
<div className="text-sm">
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signin">Sign In</Link>
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signIn">Sign In</Link>
</div>
</div>
{/* Progress bar */}
<div className="px-4 pt-12 pb-8">
<div className="px-4 pt-12 pb-[59px]">
<div className="max-w-md mx-auto w-full">
<div className="relative">
<div className="absolute left-0 top-1/2 -mt-px w-full h-0.5 bg-slate-200" aria-hidden="true"></div>
<ul className="relative flex justify-between w-full">
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-1">1</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/">1</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-2">2</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-2">2</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-3">3</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-3">3</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-4">4</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-4">4</span>
</li>
</ul>
</div>
@@ -54,29 +90,30 @@ function Onboarding2() {
</div>
<div className="px-4 py-8">
<div className="max-w-sm mx-auto">
<div className="max-w-[344px] mx-auto">
<h1 className="text-3xl text-slate-800 font-bold mb-6">Create your Account </h1>
{/* Form */}
<form>
<div>
<div className="space-y-4 mb-8">
<div>
<label className="block text-sm font-medium mb-1" htmlFor="email">Email Address <span className="text-rose-500">*</span></label>
<input id="email" className="form-input w-full" type="email" />
<label className="block text-sm font-medium mb-1" htmlFor="first_name">First name <span className="text-rose-500">*</span></label>
<input onBlur={checkFillingForm} id="firstname" onChange={(event)=>saveValueChange(event)} className="form-input w-full" type="text" />
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="name">Full Name <span className="text-rose-500">*</span></label>
<input id="name" className="form-input w-full" type="text" />
<label className="block text-sm font-medium mb-1" htmlFor="second_name">Last name <span className="text-rose-500">*</span></label>
<input onBlur={checkFillingForm} id="secondname" onChange={(event)=>saveValueChange(event)} className="form-input w-full" type="text" />
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="role">Gender <span className="text-rose-500">*</span></label>
<select id="role" className="form-select w-full">
<label className="block text-sm font-medium mb-1" htmlFor="gender">Gender <span className="text-rose-500">*</span></label>
<select onBlur={checkFillingForm} id="gender" onChange={(event)=>saveValueChange(event)} className="form-select w-full">
<option className="hidden"></option>
<option>male</option>
<option>feemale</option>
<option>female</option>
</select>
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="password">Date of birth <span className="text-rose-500">*</span></label>
<input id="password" className="form-input w-full" type="password" autoComplete="on" />
<label className="block text-sm font-medium mb-1" htmlFor="birthdate">Date of birth <span className="text-rose-500">*</span></label>
<input onBlur={checkFillingForm} id="birthdate" onChange={(event)=>saveValueChange(event)} className="form-input w-full" type="date" autoComplete="on" />
</div>
</div>
<div className="flex items-center justify-between mt-6">
@@ -86,13 +123,15 @@ function Onboarding2() {
<span className="text-sm ml-2">Email me about product news.</span>
</label>
</div>
<Link className="btn bg-indigo-500 hover:bg-indigo-600 text-white ml-3 whitespace-nowrap" to="/onboarding-3">Sign Up</Link>
<button onClick={saveStoreRegistration} className="btn bg-indigo-500 hover:bg-indigo-600 text-white ml-3 whitespace-nowrap">
<Link id="signup" to={fillingForm && "/onboarding-3"} >Sign Up</Link>
</button>
</div>
</form>
</div>
{/* Footer */}
<div className="pt-5 mt-6 border-t border-slate-200">
<div className="text-sm">
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/onboarding-2">Sign In</Link>
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signIn">Sign In</Link>
</div>
</div>
</div>
@@ -112,6 +151,6 @@ function Onboarding2() {
</main>
);
}
});
export default Onboarding2;

View File

@@ -1,10 +1,29 @@
import React from 'react';
import {observer} from "mobx-react-lite";
import { Link } from 'react-router-dom';
import {generateSvgAvatar} from "../images/GenerateOnboardingSvg/GenerateSvg";
import Logo from "../images/logo.png";
import {registrationStore} from "../store/store";
const Onboarding3 = observer(()=>{
function generatePassPhrase() {
registrationStore.generatePassPhrase();
};
function savePassPhraseInStore (copiedPhrase) {
if (copiedPhrase.split(' ').length === 12) {
registrationStore.savePastPassPhrase(copiedPhrase.trim());
}
};
function pastePassPhrase() {
navigator.clipboard.readText().then(res => savePassPhraseInStore(res));
};
function convertPassPhraseToArray() {
return registrationStore.passPhrase.split(' ').map((item, index) => ({str:item, id:index}));
};
function Onboarding3() {
const arrayBadges = ['judge', 'jelly', 'wasp', 'true', 'clog', 'forward', 'talent', 'ozone', 'belive', 'fresh', 'bulk', 'hobby']
return (
<main className="bg-white">
@@ -20,11 +39,11 @@ function Onboarding3() {
{/* Header */}
<div className="flex items-center justify-between h-16 px-4 sm:px-6 lg:px-8">
{/* Logo */}
<Link className="block" to="/">
<Link className="block" to="/dashboard">
<img alt='logo' src={Logo} width="89" height="32"/>
</Link>
<div className="text-sm">
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signin">Sign In</Link>
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signIn">Sign In</Link>
</div>
</div>
@@ -35,16 +54,16 @@ function Onboarding3() {
<div className="absolute left-0 top-1/2 -mt-px w-full h-0.5 bg-slate-200" aria-hidden="true"></div>
<ul className="relative flex justify-between w-full">
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-1">1</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/">1</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-2">2</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-2">2</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-3">3</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-3">3</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-4">4</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-slate-100 text-slate-500" to="/onboarding-4">4</span>
</li>
</ul>
</div>
@@ -58,22 +77,22 @@ function Onboarding3() {
<div className="gap-0.5">
<h1 className="text-3xl text-slate-800 font-bold mb-12">Company information </h1>
{/* htmlForm */}
<div className="grid grid-cols-4 gap-2.5 mb-14">
{arrayBadges.map(tag => (
<button key={tag} className="min-w-93px w-24 min-h-26px h-26px bg-slate-100 text-slate-500 cursor-pointer hover:bg-blue-100 hover:text-blue-600 rounded-full text-center px-2.5">
<span className="text-sm font-medium">{tag}</span>
<div className="grid grid-cols-4 gap-y-2.5 gap-[18px] mb-14">
{convertPassPhraseToArray().map(tag => (
<button key={tag.id} className="min-w-93px w-24 min-h-26px h-26px bg-slate-100 text-slate-500 cursor-pointer hover:bg-blue-100 hover:text-blue-600 rounded-full text-center px-2.5">
<span className="text-sm font-medium">{tag.str}</span>
</button>
))}
</div>
<div className="flex justify-center gap-x-5">
<button className="btn pl-9 pr-16 border-slate-200 hover:border-slate-300 text-slate-600">
<div className="flex pl-7 gap-x-5">
<button onClick={pastePassPhrase} className="btn pl-9 pr-16 border-slate-200 hover:border-slate-300 text-slate-600">
<svg className="w-4 h-4 fill-current text-slate-400 shrink-0 mb-0.5" viewBox="0 0 16 16">
<path
d="M11.7.3c-.4-.4-1-.4-1.4 0l-10 10c-.2.2-.3.4-.3.7v4c0 .6.4 1 1 1h4c.3 0 .5-.1.7-.3l10-10c.4-.4.4-1 0-1.4l-4-4zM4.6 14H2v-2.6l6-6L10.6 8l-6 6zM12 6.6L9.4 4 11 2.4 13.6 5 12 6.6z"></path>
</svg>
<span className="ml-2">Paste</span>
</button>
<button className="btn pr-11 pl-7 border-slate-200 hover:border-slate-300 text-rose-500">
<button onClick={generatePassPhrase} className="btn pr-11 pl-7 border-slate-200 hover:border-slate-300 text-rose-500">
<svg className="mb-0.5" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.5744 5.66943L13.1504 7.09343C13.4284 7.44043 13.6564 7.75743 13.8194 8.00043C13.0594 9.13043 10.9694 11.8204 8.25836 11.9854L6.44336 13.8004C6.93936 13.9244 7.45736 14.0004 8.00036 14.0004C12.7074 14.0004 15.7444 8.71643 15.8714 8.49243C16.0424 8.18843 16.0434 7.81643 15.8724 7.51243C15.8254 7.42743 15.3724 6.63143 14.5744 5.66943Z" fill="#F43F5E"/>
<path fillRule="evenodd" clipRule="evenodd" d="M1.00038 16.0002C0.744375 16.0002 0.488375 15.9022 0.293375 15.7072C-0.0976249 15.3162 -0.0976249 14.6842 0.292375 14.2942L2.82138 11.7653C1.17238 10.2913 0.198375 8.61425 0.128375 8.48925C-0.0416249 8.18625 -0.0426249 7.81725 0.126375 7.51425C0.251375 7.28925 3.24537 2.00025 8.00037 2.00025C9.33138 2.00025 10.5154 2.43125 11.5484 3.03825L14.2934 0.29325C14.6844 -0.09775 15.3164 -0.09775 15.7074 0.29325C16.0984 0.68425 16.0984 1.31625 15.7074 1.70725L1.70738 15.7072C1.51238 15.9022 1.25638 16.0002 1.00038 16.0002ZM8.00037 4.00025C5.14637 4.00025 2.95837 6.83525 2.18138 7.99925C2.55938 8.56225 3.28538 9.51025 4.24038 10.3463L6.07438 8.51225C6.02938 8.34825 6.00037 8.17825 6.00037 8.00025C6.00037 6.89525 6.89537 6.00025 8.00037 6.00025C8.17838 6.00025 8.34838 6.02925 8.51237 6.07425L10.0784 4.50825C9.43738 4.20125 8.74237 4.00025 8.00037 4.00025Z" fill="#F43F5E"/>
@@ -84,7 +103,9 @@ function Onboarding3() {
</div>
<div className="flex items-center justify-between">
<Link className="text-sm underline hover:no-underline" to="/onboarding-2">&lt;- Back</Link>
<Link className="btn bg-indigo-500 hover:bg-indigo-600 text-white ml-auto" to="/onboarding-4">Next Step -&gt;</Link>
<button className="btn bg-indigo-500 hover:bg-indigo-600 text-white ml-auto">
<Link to="/onboarding-4">Next Step -&gt;</Link>
</button>
</div>
</div>
@@ -97,7 +118,7 @@ function Onboarding3() {
{/* Image */}
<div className="flex flex-col items-center h-full w-full hidden md:block absolute top-0 bottom-0 right-0 md:w-1/2" aria-hidden="true">
<div className="flex mt-40 flex-col items-center gap-2.5">
<img className="object-cover object-center" src={generateSvgAvatar()} width="493px" height="493px" alt="Onboarding" />
<img className="object-cover object-center" src={generateSvgAvatar(registrationStore.pubKey)} width="493px" height="493px" alt="Onboarding" />
<span className="text-sm">Your generated Digital ID</span>
</div>
</div>
@@ -106,6 +127,6 @@ function Onboarding3() {
</main>
);
}
});
export default Onboarding3;

View File

@@ -1,9 +1,31 @@
import React from 'react';
import React, {useState} from 'react';
import { Link } from 'react-router-dom';
import {generateSvgAvatar} from "../images/GenerateOnboardingSvg/GenerateSvg";
import Logo from "../images/logo.png";
import {observer} from "mobx-react-lite";
import { registrationStore } from "../store/store";
const Onboarding4 = observer(() => {
const [checkBoxesSelected, setCheckBoxesSelected] = useState([]);
function createAccount() {
if(checkBoxesSelected.length === 2) {
registrationStore.pushAccountData();
sessionStorage.setItem('passPhrase', registrationStore.passPhrase);
}
};
function saveCheckBoxesValues(e) {
const { id, checked } = e.target;
setCheckBoxesSelected([...checkBoxesSelected, id]);
if (!checked) {
setCheckBoxesSelected(checkBoxesSelected.filter(item => item !== id));
}
};
const firstNameAccount = registrationStore.accountData.length && registrationStore.accountData.find(item => item.key === "firstname").value;
function Onboarding4() {
return (
<main className="bg-white">
@@ -19,31 +41,31 @@ function Onboarding4() {
{/* Header */}
<div className="flex items-center justify-between h-16 px-4 sm:px-6 lg:px-8">
{/* Logo */}
<Link className="block" to="/">
<Link className="block" to="/dashboard">
<img alt='logo' src={Logo} width="89" height="32"/>
</Link>
<div className="text-sm">
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signin">Sign In</Link>
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signIn">Sign In</Link>
</div>
</div>
{/* Progress bar */}
<div className="px-4 pt-12 pb-8">
<div className="px-4 pt-12 pb-[85px]">
<div className="max-w-md mx-auto w-full">
<div className="relative">
<div className="absolute left-0 top-1/2 -mt-px w-full h-0.5 bg-slate-200" aria-hidden="true"></div>
<ul className="relative flex justify-between w-full">
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-1">1</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/">1</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-2">2</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-2">2</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-3">3</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-3">3</span>
</li>
<li>
<Link className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-4">4</Link>
<span className="flex items-center justify-center w-6 h-6 rounded-full text-xs font-semibold bg-indigo-500 text-white" to="/onboarding-4">4</span>
</li>
</ul>
</div>
@@ -59,20 +81,22 @@ function Onboarding4() {
<circle className="text-emerald-100" cx="32" cy="32" r="32" />
<path className="text-emerald-500" d="m28.5 41-8-8 3-3 5 5 12-12 3 3z" />
</svg>
<h1 className="text-3xl text-slate-800 font-bold mb-8">Nice to meet you, Ivan 🙌</h1>
<Link className="btn bg-indigo-500 hover:bg-indigo-600 text-white" to="/">Go To Profile -&gt;</Link>
<h1 className="text-3xl text-slate-800 font-bold mb-8">{firstNameAccount ? `Nice to meet you, ${firstNameAccount} 🙌` : 'Please, go back step 2'}</h1>
<button onClick={createAccount} className="btn px-6 bg-indigo-500 hover:bg-indigo-600 text-white">
<Link id="link-dashboard" to={checkBoxesSelected.length===2 && "/dashboard"}>Go To Profile -&gt;</Link>
</button>
</div>
<div className="flex items-center justify-between mt-6">
<div className="flex items-center justify-between">
<div className="mr-1">
<label className="flex items-center">
<input type="checkbox" className="form-checkbox" />
<input id="checkbox-1" onChange={(e)=>saveCheckBoxesValues(e)} type="checkbox" className="form-checkbox" />
<span className="text-sm ml-2">I understand that Idntty cannot recover pass phrase</span>
</label>
<label className="flex items-center">
<input type="checkbox" className="form-checkbox" />
<input id="checkbox-2" onChange={(e)=>saveCheckBoxesValues(e)} type="checkbox" className="form-checkbox" />
<div className="text-sm ml-2">
<Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/">I store my pharse</Link> very carefuly
I <Link className="text-indigo-500 hover:text-indigo-600 underline" to="/">store my pharse</Link> very carefuly
</div>
</label>
</div>
@@ -88,7 +112,7 @@ function Onboarding4() {
{/* Image */}
<div className="flex flex-col items-center h-full w-full hidden md:block absolute top-0 bottom-0 right-0 md:w-1/2" aria-hidden="true">
<div className="flex mt-40 flex-col items-center gap-2.5">
<img className="object-cover object-center" src={generateSvgAvatar()} width="493px" height="493px" alt="Onboarding" />
<img className="object-cover object-center" src={generateSvgAvatar(registrationStore.pubKey)} width="493px" height="493px" alt="Onboarding" />
<span className="text-sm">Your generated Digital ID</span>
</div>
</div>
@@ -97,6 +121,6 @@ function Onboarding4() {
</main>
);
}
});
export default Onboarding4;

View File

@@ -1,8 +1,8 @@
import React from 'react';
import { Link } from 'react-router-dom';
import AuthImage from '../images/auth-image.jpg';
import AuthDecoration from '../images/auth-decoration.png';
import Logo from "../images/logo.png";
function ResetPassword() {
return (
@@ -18,23 +18,8 @@ function ResetPassword() {
<div className="flex-1">
<div className="flex items-center justify-between h-16 px-4 sm:px-6 lg:px-8">
{/* Logo */}
<Link className="block" to="/">
<svg width="32" height="32" viewBox="0 0 32 32">
<defs>
<linearGradient x1="28.538%" y1="20.229%" x2="100%" y2="108.156%" id="logo-a">
<stop stopColor="#A5B4FC" stopOpacity="0" offset="0%" />
<stop stopColor="#A5B4FC" offset="100%" />
</linearGradient>
<linearGradient x1="88.638%" y1="29.267%" x2="22.42%" y2="100%" id="logo-b">
<stop stopColor="#38BDF8" stopOpacity="0" offset="0%" />
<stop stopColor="#38BDF8" offset="100%" />
</linearGradient>
</defs>
<rect fill="#6366F1" width="32" height="32" rx="16" />
<path d="M18.277.16C26.035 1.267 32 7.938 32 16c0 8.837-7.163 16-16 16a15.937 15.937 0 01-10.426-3.863L18.277.161z" fill="#4F46E5" />
<path d="M7.404 2.503l18.339 26.19A15.93 15.93 0 0116 32C7.163 32 0 24.837 0 16 0 10.327 2.952 5.344 7.404 2.503z" fill="url(#logo-a)" />
<path d="M2.223 24.14L29.777 7.86A15.926 15.926 0 0132 16c0 8.837-7.163 16-16 16-5.864 0-10.991-3.154-13.777-7.86z" fill="url(#logo-b)" />
</svg>
<Link className="block" to="/dashboard">
<img alt='logo' src={Logo} width="89" height="32"/>
</Link>
</div>
</div>
@@ -42,7 +27,7 @@ function ResetPassword() {
<div className="max-w-sm mx-auto px-4 py-8">
<h1 className="text-3xl text-slate-800 font-bold mb-6">Reset your Password </h1>
{/* Form */}
<form>
<div>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-1" htmlFor="email">Email Address <span className="text-rose-500">*</span></label>
@@ -52,7 +37,7 @@ function ResetPassword() {
<div className="flex justify-end mt-6">
<button className="btn bg-indigo-500 hover:bg-indigo-600 text-white whitespace-nowrap">Send Reset Link</button>
</div>
</form>
</div>
</div>
</div>

View File

@@ -4,7 +4,7 @@ import {generateSvgAvatar} from "../images/GenerateOnboardingSvg/GenerateSvg";
import User06 from "../images/user-28-06.jpg";
import User08 from "../images/user-28-08.jpg";
import User09 from "../images/user-28-09.jpg";
import SharedDataRoadMap from "../partials/shareddata/SharedDataRoadmap";
import SharedDataRoadMap from "../partials/sharedData/SharedDataRoadmap";
function SharedData() {
@@ -55,9 +55,6 @@ function SharedData() {
]
};
function saveDigitalId() {
localStorage.setItem('svgAvatar', generateSvgAvatar())
}
return (
<main className="bg-white">
@@ -92,7 +89,7 @@ function SharedData() {
<div className="flex mt-40 flex-col items-center gap-2.5">
<img className="object-cover object-center" src={generateSvgAvatar()} width="493px" height="493px" alt="Onboarding" />
<span className="text-sm">{sharedDataItems.data}</span>
<Link onClick={()=>saveDigitalId()} className="mt-12 btn bg-indigo-500 hover:bg-indigo-600 text-white" to="/">Get my digital ID</Link>
<Link className="mt-12 btn bg-indigo-500 hover:bg-indigo-600 text-white" to="/dashboard">Get my digital ID</Link>
</div>
</div>

105
src/pages/SignIn.jsx Normal file
View File

@@ -0,0 +1,105 @@
import React, {useState} from 'react';
import {observer} from "mobx-react-lite";
import { Link } from 'react-router-dom';
import {generateSvgAvatar} from "../images/GenerateOnboardingSvg/GenerateSvg";
import Logo from "../images/logo.png";
import {registrationStore} from "../store/store";
const SignIn = observer(()=>{
const[passPhrase, setPassPhrase] = useState('- - - - - - - - - - - -');
const[addedPassPhrase, setAddedPassPhrase] = useState(false);
function savePassPhrase (copiedPhrase) {
if (copiedPhrase.split(' ').length === 12) {
registrationStore.savePastPassPhrase(copiedPhrase.trim());
setPassPhrase(registrationStore.passPhrase);
setAddedPassPhrase(true);
}
};
function convertPassPhraseToArray() {
return passPhrase.split(' ').map((item, index) => ({str:item, id:index}));
}
function pastePassPhrase() {
navigator.clipboard.readText().then(res => savePassPhrase(res));
};
return (
<main className="bg-white">
<div className="relative flex">
{/* Content */}
<div className="w-full md:w-1/2">
<div className="min-h-screen h-full flex flex-col after:flex-1">
<div className="flex-1">
{/* Header */}
<div className="flex items-center justify-between h-16 px-4 sm:px-6 lg:px-8">
{/* Logo */}
<Link className="block" to="/dashboard">
<img alt='logo' src={Logo} width="89" height="32"/>
</Link>
<div className="text-sm">
Have not an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/">Sign Up</Link>
</div>
</div>
</div>
<div className="px-4 mt-20 py-8">
<div className="max-w-fit mx-auto flex flex-col gap-y-36">
<div>
<h1 className="text-3xl text-slate-800 font-bold mb-12">Company information </h1>
{/* htmlForm */}
<div className="grid grid-cols-4 gap-y-2.5 gap-[18px] mb-14">
{convertPassPhraseToArray().map(tag => (
<button key={tag.id} className="min-w-[93px] min-h-[26px] bg-slate-100 text-slate-500 cursor-pointer hover:bg-blue-100 hover:text-blue-600 rounded-full text-center px-2.5">
<span className="text-sm font-medium">{tag.str}</span>
</button>
))}
</div>
<div className="flex pl-7 gap-x-5">
<button onClick={pastePassPhrase} className="btn pl-9 pr-16 border-slate-200 hover:border-slate-300 text-slate-600">
<svg className="w-4 h-4 fill-current text-slate-400 shrink-0 mb-0.5" viewBox="0 0 16 16">
<path
d="M11.7.3c-.4-.4-1-.4-1.4 0l-10 10c-.2.2-.3.4-.3.7v4c0 .6.4 1 1 1h4c.3 0 .5-.1.7-.3l10-10c.4-.4.4-1 0-1.4l-4-4zM4.6 14H2v-2.6l6-6L10.6 8l-6 6zM12 6.6L9.4 4 11 2.4 13.6 5 12 6.6z"></path>
</svg>
<span className="ml-2">Paste</span>
</button>
</div>
</div>
<div className="flex items-center justify-between">
<button className="btn bg-indigo-500 hover:bg-indigo-600 text-white ml-auto">
<Link to={addedPassPhrase && "/dashboard"}>Go To Profile -&gt;</Link>
</button>
</div>
</div>
</div>
</div>
</div>
{/* Image */}
<div className="flex flex-col items-center h-full w-full hidden md:block absolute top-0 bottom-0 right-0 md:w-1/2" aria-hidden="true">
<div className="flex mt-40 flex-col items-center gap-2.5">
<div className={`${addedPassPhrase || 'opacity-0'} w-[493px] h-[493px]`}>
<img className="object-cover object-center" alt="" src={generateSvgAvatar(registrationStore.pubKey)}/>
</div>
<span className="text-sm">Your Digital ID</span>
</div>
</div>
</div>
</main>
);
});
export default SignIn;

View File

@@ -1,100 +0,0 @@
import React, { useEffect } from 'react';
import { Link } from 'react-router-dom';
import AuthImage from '../images/auth-image.jpg';
import AuthDecoration from '../images/auth-decoration.png';
function Signin() {
useEffect(() => {
localStorage.setItem('svgKey', '')
}, [])
return (
<main className="bg-white">
<div className="relative md:flex">
{/* Content */}
<div className="md:w-1/2">
<div className="min-h-screen h-full flex flex-col after:flex-1">
{/* Header */}
<div className="flex-1">
<div className="flex items-center justify-between h-16 px-4 sm:px-6 lg:px-8">
{/* Logo */}
<Link className="block" to="/">
<svg width="32" height="32" viewBox="0 0 32 32">
<defs>
<linearGradient x1="28.538%" y1="20.229%" x2="100%" y2="108.156%" id="logo-a">
<stop stopColor="#A5B4FC" stopOpacity="0" offset="0%" />
<stop stopColor="#A5B4FC" offset="100%" />
</linearGradient>
<linearGradient x1="88.638%" y1="29.267%" x2="22.42%" y2="100%" id="logo-b">
<stop stopColor="#38BDF8" stopOpacity="0" offset="0%" />
<stop stopColor="#38BDF8" offset="100%" />
</linearGradient>
</defs>
<rect fill="#6366F1" width="32" height="32" rx="16" />
<path d="M18.277.16C26.035 1.267 32 7.938 32 16c0 8.837-7.163 16-16 16a15.937 15.937 0 01-10.426-3.863L18.277.161z" fill="#4F46E5" />
<path d="M7.404 2.503l18.339 26.19A15.93 15.93 0 0116 32C7.163 32 0 24.837 0 16 0 10.327 2.952 5.344 7.404 2.503z" fill="url(#logo-a)" />
<path d="M2.223 24.14L29.777 7.86A15.926 15.926 0 0132 16c0 8.837-7.163 16-16 16-5.864 0-10.991-3.154-13.777-7.86z" fill="url(#logo-b)" />
</svg>
</Link>
</div>
</div>
<div className="max-w-sm mx-auto px-4 py-8">
<h1 className="text-3xl text-slate-800 font-bold mb-6">Welcome back! </h1>
{/* Form */}
<form>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-1" htmlFor="email">Email Address</label>
<input id="email" className="form-input w-full" type="email" />
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="password">Password</label>
<input id="password" className="form-input w-full" type="password" autoComplete="on" />
</div>
</div>
<div className="flex items-center justify-between mt-6">
<div className="mr-1">
<Link className="text-sm underline hover:no-underline" to="/reset-password">Forgot Password?</Link>
</div>
<Link className="btn bg-indigo-500 hover:bg-indigo-600 text-white ml-3" to="/">Sign In</Link>
</div>
</form>
{/* Footer */}
<div className="pt-5 mt-6 border-t border-slate-200">
<div className="text-sm">
Dont you have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signup">Sign Up</Link>
</div>
{/* Warning */}
<div className="mt-5">
<div className="bg-amber-100 text-amber-600 px-3 py-2 rounded">
<svg className="inline w-3 h-3 shrink-0 fill-current mr-2" viewBox="0 0 12 12">
<path d="M10.28 1.28L3.989 7.575 1.695 5.28A1 1 0 00.28 6.695l3 3a1 1 0 001.414 0l7-7A1 1 0 0010.28 1.28z" />
</svg>
<span className="text-sm">
To support you during the pandemic super pro features are free until March 31st.
</span>
</div>
</div>
</div>
</div>
</div>
</div>
{/* Image */}
<div className="hidden md:block absolute top-0 bottom-0 right-0 md:w-1/2" aria-hidden="true">
<img className="object-cover object-center w-full h-full" src={AuthImage} width="760" height="1024" alt="Authentication" />
<img className="absolute top-1/4 left-0 transform -translate-x-1/2 ml-8 hidden lg:block" src={AuthDecoration} width="218" height="224" alt="Authentication decoration" />
</div>
</div>
</main>
);
}
export default Signin;

View File

@@ -1,101 +0,0 @@
import React from 'react';
import { Link } from 'react-router-dom';
import AuthImage from '../images/auth-image.jpg';
import AuthDecoration from '../images/auth-decoration.png';
function Signup() {
return (
<main className="bg-white">
<div className="relative md:flex">
{/* Content */}
<div className="md:w-1/2">
<div className="min-h-screen h-full flex flex-col after:flex-1">
{/* Header */}
<div className="flex-1">
<div className="flex items-center justify-between h-16 px-4 sm:px-6 lg:px-8">
{/* Logo */}
<Link className="block" to="/">
<svg width="32" height="32" viewBox="0 0 32 32">
<defs>
<linearGradient x1="28.538%" y1="20.229%" x2="100%" y2="108.156%" id="logo-a">
<stop stopColor="#A5B4FC" stopOpacity="0" offset="0%" />
<stop stopColor="#A5B4FC" offset="100%" />
</linearGradient>
<linearGradient x1="88.638%" y1="29.267%" x2="22.42%" y2="100%" id="logo-b">
<stop stopColor="#38BDF8" stopOpacity="0" offset="0%" />
<stop stopColor="#38BDF8" offset="100%" />
</linearGradient>
</defs>
<rect fill="#6366F1" width="32" height="32" rx="16" />
<path d="M18.277.16C26.035 1.267 32 7.938 32 16c0 8.837-7.163 16-16 16a15.937 15.937 0 01-10.426-3.863L18.277.161z" fill="#4F46E5" />
<path d="M7.404 2.503l18.339 26.19A15.93 15.93 0 0116 32C7.163 32 0 24.837 0 16 0 10.327 2.952 5.344 7.404 2.503z" fill="url(#logo-a)" />
<path d="M2.223 24.14L29.777 7.86A15.926 15.926 0 0132 16c0 8.837-7.163 16-16 16-5.864 0-10.991-3.154-13.777-7.86z" fill="url(#logo-b)" />
</svg>
</Link>
</div>
</div>
<div className="max-w-sm mx-auto px-4 py-8">
<h1 className="text-3xl text-slate-800 font-bold mb-6">Create your Account </h1>
{/* Form */}
<form>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-1" htmlFor="email">Email Address <span className="text-rose-500">*</span></label>
<input id="email" className="form-input w-full" type="email" />
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="name">Full Name <span className="text-rose-500">*</span></label>
<input id="name" className="form-input w-full" type="text" />
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="role">Your Role <span className="text-rose-500">*</span></label>
<select id="role" className="form-select w-full">
<option>Designer</option>
<option>Developer</option>
<option>Accountant</option>
</select>
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="password">Password</label>
<input id="password" className="form-input w-full" type="password" autoComplete="on" />
</div>
</div>
<div className="flex items-center justify-between mt-6">
<div className="mr-1">
<label className="flex items-center">
<input type="checkbox" className="form-checkbox" />
<span className="text-sm ml-2">Email me about product news.</span>
</label>
</div>
<Link className="btn bg-indigo-500 hover:bg-indigo-600 text-white ml-3 whitespace-nowrap" to="/">Sign Up</Link>
</div>
</form>
{/* Footer */}
<div className="pt-5 mt-6 border-t border-slate-200">
<div className="text-sm">
Have an account? <Link className="font-medium text-indigo-500 hover:text-indigo-600" to="/signin">Sign In</Link>
</div>
</div>
</div>
</div>
</div>
{/* Image */}
<div className="hidden md:block absolute top-0 bottom-0 right-0 md:w-1/2" aria-hidden="true">
<img className="object-cover object-center w-full h-full" src={AuthImage} width="760" height="1024" alt="Authentication" />
<img className="absolute top-1/4 left-0 transform -translate-x-1/2 ml-8 hidden lg:block" src={AuthDecoration} width="218" height="224" alt="Authentication decoration" />
</div>
</div>
</main>
);
}
export default Signup;

View File

@@ -1,34 +1,100 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import { registrationStore } from "../../store/store";
import Sidebar from '../../partials/Sidebar';
import { observer } from 'mobx-react-lite';
import Header from '../../partials/Header';
import ProfileTable from '../../partials/digitalId/ProfileTable';
import ProfileTable from '../../partials/profile/ProfileTable';
import Image from '../../images/transactions-image-04.svg';
import ProfileIcon from '../../images/profile-icon.svg';
import Avatar01 from '../../images/avatar-01.jpg';
import Avatar02 from '../../images/avatar-02.jpg';
import Avatar03 from '../../images/avatar-03.jpg';
function Profile () {
const initialPropertyValues = ['First name', 'Second name', 'Birthdate', 'Gender', 'National doctype', 'National doc ID', 'National doc issue date', 'National doc expiry date'];
const Profile = observer (() => {
const defaultValues = {
label: '',
value: '',
seed: String(Math.floor(Math.random() * 90000000000000000000), 10),
};
const [sidebarOpen, setSidebarOpen] = useState(false);
const [buttonPanelOpen, setButtonPanelOpen] = useState(true);
const [removePanelOpen, setRemovePanelOpen] = useState(false);
const [changePanelOpen, setChangePanelOpen] = useState(false);
const [toggle, setToggle] = useState(true);
const [addPanelOpen, setAddPanelOpen] = useState(false);
const [updatePanelOpen, setUpdatePanelOpen] = useState(false);
const [selectedItems, setSelectedItems] = useState([]);
const [propertyValues, setPropertyValues] = useState([]);
const [updatedValues, setUpdatedValues] = useState([defaultValues]);
const [addedValues, setAddedValues] = useState(defaultValues);
const [isCheck, setIsCheck] = useState([]);
useEffect(() => {
handleSelectedItems(isCheck);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isCheck]);
const handleClick = e => {
const { id, checked } = e.target;
setIsCheck([...isCheck, id]);
if (!checked || !id) {
setIsCheck(isCheck.filter(item => item !== id));
}
};
const openHint = () => {
if (!addedValues.label) {
setPropertyValues(initialPropertyValues);
}
};
const changeAddedValues = (value, field) => {
setAddedValues((prevState) => ({
...prevState,
[field]: value,
}))
};
const changeUpdatedValues = (value, field, key) => {
setUpdatedValues((prevState) =>
prevState.map((elem) => (
(elem.key === key) ? {
...elem,
[field]: value,
} : elem
))
)
};
const selectHint = (element) => {
changeAddedValues(element, 'label');
setPropertyValues([]);
}
const closeHint = (eventTarget) => {
if (!eventTarget || eventTarget.tabIndex !== -1) {
setPropertyValues([]);
}
};
const handleSelectedItems = (selectedItems) => {
setSelectedItems([...selectedItems]);
setUpdatedValues(registrationStore.decryptedAccountData.filter(({ key }) => selectedItems.includes(key))
.map(elem => (
(!elem.seed) ? {
...elem,
seed: String(Math.floor(Math.random() * 90000000000000000000), 10),
}: elem)));
if (selectedItems.length > 0) {
setButtonPanelOpen(false);
setAddPanelOpen(false);
setChangePanelOpen(true);
}
if (removePanelOpen === true) {
if (removePanelOpen === true || updatePanelOpen === true) {
setChangePanelOpen(false);
}
if (selectedItems.length === 0) {
setRemovePanelOpen(false);
setUpdatePanelOpen(false);
setButtonPanelOpen(true);
setChangePanelOpen(false);
}
@@ -37,157 +103,103 @@ function Profile () {
const openAddPanel = () => {
setAddPanelOpen(true);
setButtonPanelOpen(false);
}
};
const sendAddedData = () => {
const checkingAddedData = !registrationStore.decryptedAccountData
.some((element) => element.label === addedValues.label) && (addedValues.seed.length === 20);
if (checkingAddedData) {
setAddPanelOpen(false);
setButtonPanelOpen(true);
setAddedValues(defaultValues);
addDataParameters();
}
};
const sendUpdatedData = () => {
setUpdatePanelOpen(false);
changeDataParameters();
setChangePanelOpen(true);
setIsCheck([]);
};
const deleteDataParameters = () => {
const changeData = registrationStore.decryptedAccountData.filter(item=>!selectedItems.includes(item.key))
registrationStore.pushAccountData(changeData);
};
const changeInitialArray = () => {
let newArr = [];
registrationStore.decryptedAccountData.map(elem => {
updatedValues.forEach(item => {
if (elem.label === item.label) {
newArr.push({
...elem,
'value': item.value,
'seed': item.seed,
})
}
})
if (!newArr.find(element => element.label === elem.label)) {
newArr.push(elem);
}
})
return newArr;
};
const changeDataParameters = () => {
const updatedData = changeInitialArray();
registrationStore.pushAccountData(updatedData);
};
const addDataParameters = () => {
addedValues.key = addedValues.label.toLowerCase().split(' ').join('');
registrationStore.pushAccountData(registrationStore.decryptedAccountData.concat(addedValues));
};
const cancelAddPanel = () => {
setAddedValues(defaultValues);
setAddPanelOpen(false);
setButtonPanelOpen(true);
}
};
const cancelUpdatePanel = () => {
setUpdatedValues(registrationStore.decryptedAccountData.filter(({ key }) => selectedItems.includes(key))
.map(elem => (
(!elem.seed) ? {
...elem,
seed: String(Math.floor(Math.random() * 90000000000000000000), 10),
}: elem)));
setUpdatePanelOpen(false);
setChangePanelOpen(true);
setIsCheck([]);
};
const openRemovePanel = () => {
setRemovePanelOpen(true);
setChangePanelOpen(false);
}
};
const applyRemovePanel = () => {
const openUpdatePanel = () => {
setUpdatePanelOpen(true);
setChangePanelOpen(false);
};
const applyDataDeletion = () => {
setRemovePanelOpen(false);
setButtonPanelOpen(true);
}
deleteDataParameters();
setIsCheck([]);
};
const userData = [
{
id: '0',
category: 'General',
validated: true,
blockchained: true,
image: ProfileIcon,
value: 'Dominik',
property: 'First name',
status: 'Completed',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: [Avatar01, Avatar02, Avatar03]
},
{
id: '1',
category: 'General',
validated: true,
blockchained: true,
image: ProfileIcon,
value: 'Lamakani',
property: 'Second name',
status: 'Progress',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: null
},
{
id: '2',
category: 'General',
validated: true,
blockchained: true,
image: ProfileIcon,
value: '05.10.1983',
property: 'Birthdate',
status: 'Incorrect',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: null
},
{
id: '3',
category: 'General',
validated: true,
blockchained: true,
image: ProfileIcon,
value: 'Male',
property: 'Gender',
status: 'Stored',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: null
},
{
id: '4',
category: 'Nationality',
validated: true,
blockchained: true,
image: ProfileIcon,
value: 'United Kindom',
property: 'Residence',
status: 'Completed',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: [Avatar01, Avatar02, Avatar03]
},
{
id: '5',
category: 'Nationality',
validated: true,
blockchained: true,
image: ProfileIcon,
value: 'Passport',
property: 'Document type',
status: 'Progress',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: [Avatar01, Avatar02, Avatar03]
},
{
id: '6',
category: 'Nationality',
validated: true,
blockchained: true,
image: ProfileIcon,
value: 'A123B3143',
property: 'Document ID',
status: 'Incorrect',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: null
},
{
id: '7',
category: 'Nationality',
validated: true,
blockchained: true,
image: ProfileIcon,
value: '05.10.2012',
property: 'Issue date',
status: 'Stored',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: null
},
{
id: '8',
category: 'Nationality',
validated: true,
blockchained: true,
image: ProfileIcon,
value: '05.10.2032',
property: 'Expiry date',
status: 'Stored',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: null
},
{
id: '9',
category: 'Social',
validated: true,
blockchained: true,
image: ProfileIcon,
value: '@lamakani',
property: 'Telegram',
status: 'Completed',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: null
},
{
id: '10',
category: 'Social',
validated: true,
blockchained: true,
image: ProfileIcon,
value: '@lamakani',
property: 'Telegram',
status: 'Progress',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: [Avatar01, Avatar02, Avatar03]
},
]
const handleInput = (text, field) => {
changeAddedValues(text, field);
setPropertyValues(initialPropertyValues);
if (text) {
let reg = new RegExp(`^${text}`, 'img');
setPropertyValues((prevState) => prevState.filter((element) => element.match(reg)));
}
};
return (
<div className="flex h-screen overflow-hidden">
@@ -222,7 +234,9 @@ function Profile () {
</ul>
</div>
{/* Table */}
<ProfileTable selectedItems={handleSelectedItems} userData={userData}/>
<div className='w-[828px]'>
<ProfileTable isCheck={isCheck} handleClick={handleClick} userData={registrationStore.decryptedAccountData}/>
</div>
</div>
{/* Left sidebar */}
<div>
@@ -242,26 +256,131 @@ function Profile () {
</div>
<div className="ml-2.5">
{/* Add panel */}
<div className={`${!addPanelOpen && 'hidden'} bg-white p-5 shadow-lg rounded-sm border border-slate-200 lg:w-72 xl:w-80 mb-11`}>
<div className="flex flex-col gap-y-3">
<div>
<label className="block text-sm font-medium mb-1" htmlFor="mandatory">Property <span className="text-rose-500">*</span></label>
<input id="property" className="form-input w-full" type="text" required />
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="mandatory">Value <span className="text-rose-500">*</span></label>
<input id="value" className="form-input w-full" type="text" required />
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="mandatory">Seed <span className="text-rose-500">*</span></label>
<input id="seed" className="form-input w-full" type="text" required />
<div className={`${!addPanelOpen && 'hidden'} relative flex flex-col bg-white p-5 shadow-lg rounded-sm border border-slate-200 lg:w-72 xl:w-80 mb-11`}>
<div className='relative z-20'>
<label className="block text-sm font-medium mb-1" htmlFor="mandatory">Property <span className="text-rose-500">*</span></label>
<input
autoComplete='off'
id="label"
className="form-input w-full"
type="text"
required
onInput={(e) => handleInput(e.target.value, 'label')}
value={addedValues.label}
onClick={openHint}
onBlur={(e) => closeHint(e.relatedTarget)}
/>
<div tabIndex='-1' className={`absolute w-full box-border bg-white flex flex-col gap-y-2 py-2 pl-2 border border-t-0 border-slate-200 rounded ${(propertyValues.length > 0) || 'hidden'}`}>
<ul>
{propertyValues.map((element, index) => (
<li className='hover:text-indigo-600 cursor-pointer' key={index} onClick={() => selectHint(element)}>{element}</li>
))}
</ul>
</div>
</div>
<div className='my-3 z-10'>
<label className="block text-sm font-medium mb-1" htmlFor="mandatory">Value <span className="text-rose-500">*</span></label>
<input
autoComplete='off'
id="value"
className="form-input w-full"
type="text"
required
onClick={() => setPropertyValues([])}
onChange={(e) => changeAddedValues(e.target.value, 'value')}
value={addedValues.value}
/>
</div>
<div className='z-10'>
<label className="block text-sm font-medium mb-1" htmlFor="mandatory">Seed <span className="text-rose-500">*</span></label>
<input
autoComplete='off'
id="seed"
className="form-input w-full"
type="text"
required
onClick={() => setPropertyValues([])}
onChange={(e) => changeAddedValues(e.target.value, 'seed')}
value={addedValues.seed}
/>
</div>
<div className="flex flex-row z-10 justify-between pt-[18px] pb-[23px] items-center border-b border-slate-200">
<span className="block text-sm font-medium">Store data on blockchain</span>
<div className="flex items-center">
<div className="form-switch">
<input type="checkbox" id="blockcheined" className="sr-only" checked={toggle} onChange={() => setToggle(!toggle)} />
<label className="bg-slate-400" htmlFor="switch-1">
<span className="bg-white shadow-sm" aria-hidden="true"></span>
</label>
</div>
</div>
</div>
{/* Buttons */}
<div className="flex flex-row z-10 justify-end gap-x-2 pt-[18px] pb-[14px] items-end">
<button
className="btn-sm bg-white border-slate-200 hover:bg-slate-50 text-slate-600"
onClick={cancelAddPanel}
>
Cansel
</button>
<button
className="btn-sm bg-indigo-500 hover:bg-indigo-600 text-white"
onClick={sendAddedData}
>
Send
</button>
</div>
</div>
{/* Update panel */}
<div className={`${!updatePanelOpen && 'hidden'} bg-white p-5 shadow-lg rounded-sm border border-slate-200 lg:w-72 xl:w-80 mb-11`}>
{updatedValues.map((item, index) => (
<div key={index} className="flex flex-col gap-y-3">
<div>
<label className="block text-sm font-medium mb-1" htmlFor="mandatory">Property <span className="text-rose-500">*</span></label>
<input
id={`${item.key}:label`}
className="form-input w-full"
type="text"
required
onChange={(e) => changeUpdatedValues(e.target.value, 'label', item.key)}
value={item.label}
disabled='disabled'
/>
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="mandatory">Value <span className="text-rose-500">*</span></label>
<input
autoComplete='off'
id={`${item.key}:value`}
className="form-input w-full"
type="text"
required
onChange={(e) => changeUpdatedValues(e.target.value, 'value', item.key)}
value={item.value}
/>
</div>
<div>
<label className="block text-sm font-medium mb-1" htmlFor="mandatory">Seed <span className="text-rose-500">*</span></label>
<input
autoComplete='off'
id={`${item.key}:seed`}
className="form-input w-full"
type="text"
required
onChange={(e) => changeUpdatedValues(e.target.value, 'seed', item.key)}
value={item.seed}
/>
</div>
{(updatedValues[index+1]) ? (
<div className="mt-2 mb-3.5 items-center border-b border-slate-200"></div>
) : null}
</div>
))}
<div className="flex flex-row justify-between pt-[16px] pb-[23px] items-center border-b border-slate-200">
<span className="block text-sm font-medium">Store data on blockchain</span>
<div className="flex items-center">
<div className="form-switch">
<input type="checkbox" id="switch-1" className="sr-only" checked={toggle} onChange={() => setToggle(!toggle)} />
<input type="checkbox" id="blockcheined" className="sr-only" checked={toggle} onChange={() => setToggle(!toggle)} />
<label className="bg-slate-400" htmlFor="switch-1">
<span className="bg-white shadow-sm" aria-hidden="true"></span>
</label>
@@ -272,27 +391,27 @@ function Profile () {
<div className="flex flex-row justify-end gap-x-2 pt-[18px] pb-[14px] items-end">
<button
className="btn-sm bg-white border-slate-200 hover:bg-slate-50 text-slate-600"
onClick={cancelAddPanel}
onClick={cancelUpdatePanel}
>
Cansel
</button>
<button
className="btn-sm bg-indigo-500 hover:bg-indigo-600 text-white"
onClick={cancelAddPanel}
onClick={sendUpdatedData}
>
Send
</button>
</div>
</div>
{/* Remove panel */}
<div className={`${!removePanelOpen && 'hidden'} bg-white p-5 pb-[190px] shadow-lg rounded-sm border border-slate-200 lg:w-72 xl:w-80 mb-12`}>
<h2 className="grow text-base font-semibold text-slate-800 truncate mb-2.5">Summary</h2>
<div className={`${!removePanelOpen && 'hidden'} bg-white px-5 pt-4 pb-[190px] shadow-lg rounded-sm border border-slate-200 lg:w-72 xl:w-80 mb-12`}>
<h2 className="grow text-base font-semibold text-slate-800 truncate mb-2">Summary</h2>
<div className="flex flex-col">
{userData.filter(({ id }) => selectedItems.includes(id)).map(item => (
<span key={item.id} className="text-sm font-normal text-slate-600 py-3 border-b border-slate-200">{item.property}</span>
{registrationStore.decryptedAccountData.filter(({ key }) => selectedItems.includes(key)).map(item => (
<span key={item.label} className="text-sm font-normal text-slate-600 py-3 border-b border-slate-200">{item.label}</span>
))}
</div>
<div className="flex flex-row justify-between pt-[16px] pb-[23px] items-center">
<div className="flex flex-row justify-between pt-[16px] pb-7 items-center">
<span className="block text-sm font-medium">On blockchain too</span>
<div className="flex items-center">
<div className="form-switch">
@@ -306,7 +425,7 @@ function Profile () {
<div className="flex flex-row justify-end gap-x-2 pt-[20px] pb-[16px] items-end">
<button
className="btn w-full bg-indigo-500 hover:bg-indigo-600 text-white px-[100px] justify-start"
onClick={applyRemovePanel}
onClick={applyDataDeletion}
>
<svg className="w-4 h-4 fill-current shrink-0" viewBox="0 0 16 16">
<path d="m2.457 8.516.969-.99 2.516 2.481 5.324-5.304.985.989-6.309 6.284z" />
@@ -351,7 +470,7 @@ function Profile () {
<span className="font-medium text-slate-700 text-right">IT17 2207 1010 0504 0006 88</span>
</div>
<div className="flex justify-between space-x-1">
<span className="italic">Transacion::</span>
<span className="italic">Transaction:</span>
<span className="font-medium text-slate-700 text-right">145 bytes</span>
</div>
</div>
@@ -369,7 +488,10 @@ function Profile () {
</svg>
<span className="ml-2">Remove</span>
</button>
<button className="btn w-full border-slate-200 hover:border-slate-300 text-slate-600 px-[100px] justify-start">
<button
className="btn w-full border-slate-200 hover:border-slate-300 text-slate-600 px-[100px] justify-start"
onClick={openUpdatePanel}
>
<svg className="w-4 h-4 fill-rose-500 shrink-0" viewBox="0 0 16 16">
<path d="M14.682 2.318A4.485 4.485 0 0 0 11.5 1 4.377 4.377 0 0 0 8 2.707 4.383 4.383 0 0 0 4.5 1a4.5 4.5 0 0 0-3.182 7.682L8 15l6.682-6.318a4.5 4.5 0 0 0 0-6.364Zm-1.4 4.933L8 12.247l-5.285-5A2.5 2.5 0 0 1 4.5 3c1.437 0 2.312.681 3.5 2.625C9.187 3.681 10.062 3 11.5 3a2.5 2.5 0 0 1 1.785 4.251h-.003Z" />
</svg>
@@ -390,6 +512,6 @@ function Profile () {
</div>
</div>
)
}
})
export default Profile;
export default Profile

View File

@@ -1,70 +1,17 @@
import React, { useState } from 'react';
import {observer} from "mobx-react-lite";
import Sidebar from '../../partials/Sidebar';
import Header from '../../partials/Header';
import ValidateTable from "../../partials/validate/ValidateTable";
import ValidatePanel from "../../partials/validate/ValidatePanel";
import ValidateRoadMap from "../../partials/validationlog/ValidateRoadMap";
import ValidateRoadMap from "../../partials/validationLog/ValidateRoadMap";
import {Link} from "react-router-dom";
import User06 from "../../images/user-28-06.jpg";
import User08 from "../../images/user-28-08.jpg";
import User09 from "../../images/user-28-09.jpg";
import User05 from "../../images/user-28-05.jpg";
import {registrationStore} from "../../store/store";
function Validate () {
const Validate = observer(() => {
const [sidebarOpen, setSidebarOpen] = useState(false);
const [validatePanelOpen, setValidatePanelOpen] = useState(true);
const validateItems = [
{
id: '40',
name: 'Today',
data: '7234ABC342342352345',
usersImges: [
{
size: 24,
img: User06,
imgId: "343"
},
{
size: 24,
img: User08,
imgId: "345"
},
{
size: 24,
img: User09,
imgId: "321"
},
{
size: 24,
img: User05,
imgId: "387"
},
],
items: [
{
dataSeason: '7234ABC342342352345',
id: '555',
text: 'Second name for',
checked: true
},
{
dataSeason: '7234ABC342342352345',
id: '534',
text: 'Gender name for',
checked: true
},
{
dataSeason: '7234ABC342342352345',
id: '567',
text: 'Document ID name for',
checked: true
},
]
},
];
return (
<div className="flex h-screen overflow-hidden">
{/* Sidebar */}
@@ -73,7 +20,7 @@ function Validate () {
<div className="relative flex flex-col flex-1 overflow-y-auto overflow-x-hidden">
{/* Site header */}
<Header sidebarOpen={sidebarOpen} setSidebarOpen={setSidebarOpen} />
<main>
<main className="relative">
<div className="px-4 sm:px-6 lg:px-8 py-8 w-full max-w-9xl mx-auto">
<div className="w-fit">
{/* Page header */}
@@ -107,10 +54,10 @@ function Validate () {
</ul>
</div>
<ValidateTable setValidatePanelOpen={setValidatePanelOpen}/>
<div className="pb-8 border-b border-zinc-200 mt-12">
<h1 className="text-2xl md:text-3xl text-slate-800 font-bold">Digiatl ID validation log </h1>
<div className="pb-8 border-b border-zinc-200 mt-[50px]">
<h1 className="text-2xl md:text-3xl text-slate-800 font-bold">Digital ID validation log </h1>
</div>
{validateItems.map(item => {
{registrationStore.transactionsInfo.map(item => {
return <ValidateRoadMap season={item} key={item.id}/>
})}
</div>
@@ -120,6 +67,6 @@ function Validate () {
</div>
</div>
)
}
})
export default Validate;

View File

@@ -1,115 +1,13 @@
import React, { useState } from 'react';
import ValidateRoadMap from "../../partials/validationlog/ValidateRoadMap";
import React, {useState} from 'react';
import ValidateRoadMap from "../../partials/validationLog/ValidateRoadMap";
import {observer} from "mobx-react-lite";
import Sidebar from '../../partials/Sidebar';
import Header from '../../partials/Header';
import User05 from "../../images/user-28-05.jpg";
import User08 from "../../images/user-28-08.jpg";
import User09 from "../../images/user-28-09.jpg";
import User06 from "../../images/user-28-06.jpg";
import User03 from "../../images/user-28-03.jpg";
import User01 from "../../images/user-28-01.jpg";
import {registrationStore} from "../../store/store";
function ValidationLog () {
const ValidationLog = observer(() => {
const [sidebarOpen, setSidebarOpen] = useState(false);
const logItems = [
{
id: '20',
name: 'Today',
data: '7234ABC342342352345',
usersImges: [
{
size: 24,
img: User06,
imgId: "249"
},
{
size: 24,
img: User08,
imgId: "212"
},
{
size: 24,
img: User09,
imgId: "217"
},
{
size: 24,
img: User05,
imgId: "276"
},
],
items: [
{
dataSeason: '7234ABC342342352345',
id: '434',
text: 'Second name',
checked: true
},
{
dataSeason: '7234ABC342342352345',
id: '476',
text: 'First name by',
checked: true
},
{
dataSeason: '7234ABC342342352345',
id: '422',
text: 'Document name by',
checked: true
},
]
},
{
id: '30',
name: 'Last Week',
data: '7234ABC342342352345',
usersImges: [
{
size: 24,
img: User06,
imgId: "145"
},
{
size: 24,
img: User08,
imgId: "182"
},
{
size: 24,
img: User09,
imgId: "154"
},
{
size: 24,
img: User05,
imgId: "114"
},
],
items: [
{
dataSeason: '7234ABC342342352345',
id: '654',
text: 'Gender name by',
checked: true
},
{
dataSeason: '7234ABC342342352345',
id: '617',
text: 'Second name Updated',
checked: false
},
{
dataSeason: '7234ABC342342352345',
id: '643',
text: 'Gender name by',
checked: true
},
]
},
]
return (
<div className="flex h-screen overflow-hidden">
{/* Sidebar */}
@@ -123,67 +21,15 @@ function ValidationLog () {
{/* Page header */}
<div className="pb-8 border-b border-zinc-200">
{/* Title */}
<h1 className="text-2xl md:text-3xl text-slate-800 font-bold">Digiatl ID transaction log </h1>
<h1 className="text-2xl md:text-3xl text-slate-800 font-bold">Digital ID transaction log </h1>
</div>
{/*Psosts*/}
<div className="max-w-3xl m-auto mt-8">
<div className="max-w-3xl m-auto mt-6">
<div className="xl:-translate-x-16 max-w-fit">
{/* PostsID */}
{logItems.map(item => {
return <ValidateRoadMap season={item} key={item.id} />
{registrationStore.transactionsInfo.map(item => {
return <ValidateRoadMap season={item} key={item.id}/>
})}
{/* Post */}
<article className="pt-6">
<div className="xl:flex">
<div className="w-32 shrink-0">
<h2 className="text-xl leading-snug font-bold text-slate-800 xl:leading-7 mb-4 xl:mb-0">Even earlier</h2>
</div>
<div className="grow pb-6 border-b border-slate-200">
<header>
<div className="flex flex-nowrap items-center space-x-2 mb-6">
{/* Avatars */}
<div className="flex shrink-0 -space-x-3 -ml-px">
<a className="block" href="#0">
<img className="rounded-full border-2 border-white box-content" src={User03} width="28" height="28" alt="User 03" />
</a>
<a className="block" href="#0">
<img className="rounded-full border-2 border-white box-content" src={User01} width="28" height="28" alt="User 01" />
</a>
</div>
<div className="text-slate-400">·</div>
</div>
</header>
{/* List */}
<ul className="-my-2">
{/* List item */}
<li className="relative py-2">
<div className="flex items-center mb-1">
<div className="absolute left-0 h-full w-0.5 bg-slate-200 self-start ml-2.5 -translate-x-1/2 translate-y-3" aria-hidden="true"></div>
<div className="absolute left-0 rounded-full bg-white" aria-hidden="true">
<svg className="w-5 h-5 fill-current text-slate-400" viewBox="0 0 20 20">
<path d="M10 18a8 8 0 100-16 8 8 0 000 16zm0 2C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10z" />
</svg>
</div>
<h3 className="text-lg font-bold text-slate-800 pl-9">Product V1 - Early Access</h3>
</div>
<div className="pl-9">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div>
</li>
{/* List item */}
<li className="relative py-2">
<div className="flex items-center mb-1">
<div className="absolute left-0 rounded-full bg-white" aria-hidden="true">
<svg className="w-5 h-5 fill-current text-slate-400" viewBox="0 0 20 20">
<path d="M10 18a8 8 0 100-16 8 8 0 000 16zm0 2C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10z" />
</svg>
</div>
<h3 className="text-lg font-bold text-slate-800 pl-9">Web3 Compatibility</h3>
</div>
<div className="pl-9">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div>
</li>
</ul>
</div>
</div>
</article>
</div>
</div>
</div>
@@ -191,6 +37,6 @@ function ValidationLog () {
</div>
</div>
)
}
})
export default ValidationLog;

View File

@@ -1,83 +1,13 @@
import React, { useState } from 'react';
import Sidebar from '../../partials/Sidebar';
import Header from '../../partials/Header';
import {registrationStore} from "../../store/store";
import { observer } from 'mobx-react-lite';
function Verify () {
const Verify = observer(() => {
const [sidebarOpen, setSidebarOpen] = useState(false);
const [descriptionOpen, setDescriptionOpen] = useState(false);
const verifiedData = [
{
"date": "31.05.2022 10:48",
"fields": [
{
"name": "Residence",
"value": "United Kindom",
"hash1": "7234ABC3423423523457234ABC34234",
"hash2": "7234ABC3423423523457234ABC34234"
},
{
"name": "Document ID",
"value": "A1321313",
"hash1": "7234ABC3423423523457234ABC34234",
"hash2": "7234ABC3423423523457234ABC34234"
},
{
"name": 'Document ID',
"value": 'A3451313',
"hash1": '9584ABC3423423523457234ABC34234',
"hash2": '9584ABC3423423523457234ABC34234'
}
]
},
{
"date": "31.05.2022 10:48",
"fields": [
{
"name": 'Residence',
"value": 'Holland',
"hash1": '1024ABC3423423523457234ABC34234',
"hash2": '1024ABC3423423523457234ABC34234'
},
{
"name": 'Document ID',
"value": 'B3451313',
"hash1": '7893ABC3423423523457234ABC34234',
"hash2": '7893ABC3423423523457234ABC34234'
},
{
"name": 'Document ID',
"value": 'A3451313',
"hash1": '7286ABC3423423523457234ABC34234',
"hash2": '7286ABC3423423523457234ABC34234'
},
]
},
{
"date": "31.05.2022 10:48",
"fields": [
{
"name": 'Residence',
"value": 'China',
"hash1": '0000ABC3423423523457234ABC34234',
"hash2": '0000ABC3423423523457234ABC34234'
},
{
"name": 'Document ID',
"value": 'C3451313',
"hash1": '1230ABC3423423523457234ABC34234',
"hash2": '1230ABC3423423523457234ABC34234'
},
{
"name": 'Document ID',
"value": 'D3451313',
"hash1": '4483ABC3423423523457234ABC34234',
"hash2": '4483ABC3423423523457234ABC34234'
},
]
}
];
return (
<div className="flex h-screen overflow-hidden">
{/* Sidebar */}
@@ -112,13 +42,10 @@ function Verify () {
</div>
{/* Block */}
<div className="flex flex-col gap-y-4">
{verifiedData.map((item, index) => (
{registrationStore.sharedData.map((item, index) => (
<div key={index} className="w-[1095px] pl-5 pr-[13px] pb-8 bg-white border border-slate-200 rounded shadow-[0_4px_6px_-1px_rgba(5,23,42,0.08)]">
{/* Header */}
<div className="flex justify-between items-center h-[42px]">
<span className="font-normal text-descriptionSize text-slate-500" >
Yesterday at {item.date.slice(-5)} AM
</span>
<div className="flex justify-end items-center h-[42px]">
{/* Buttons */}
<div className="flex gap-x-[6px]">
<div className="flex items-center">
@@ -131,9 +58,8 @@ function Verify () {
</div>
<div className="flex items-center">
<button
className={`text-slate-400 hover:text-slate-500 transform ${descriptionOpen && 'rotate-180'}`}
aria-expanded={descriptionOpen}
onClick={() => setDescriptionOpen(!descriptionOpen)}
className={`text-slate-400 hover:text-slate-500 transform ${descriptionOpen && 'rotate-180'}`}
aria-expanded={descriptionOpen}
>
<svg className="w-8 h-8 fill-current" viewBox="0 0 32 32">
<path d="M16 20l-5.4-5.4 1.4-1.4 4 4 4-4 1.4 1.4z" />
@@ -144,20 +70,18 @@ function Verify () {
</div>
{/* Content */}
<div className='flex flex-col gap-y-[9px]'>
{item.fields.map((elem) => (
<div className='flex gap-y-2'>
{item.data.map((elem, index) => (
<div key={index} className='flex gap-y-2'>
<div className='flex flex-col'>
<div className='flex flex-row items-center'>
<span className='font-semibold text-slate-800 text-base w-[204px]'>{elem.value}</span>
<span className='font-semibold text-descriptionSize text-slate-600 underline w-80'>{elem.hash1}</span>
<span className='font-semibold text-descriptionSize text-slate-600 underline w-80'>{elem.hash2}</span>
<span className='font-inter font-semibold text-slate-800 text-base w-[204px]'>{elem.label}</span>
<span className='font-inter truncate font-semibold text-descriptionSize text-slate-600 underline w-[770px]'>{elem.value}</span>
</div>
<span className='font-normal text-xxs'>{elem.name}</span>
</div>
</div>
))}
</div>
</div>
</div>
))}
</div>
</div>
@@ -165,6 +89,6 @@ function Verify () {
</div>
</div>
)
}
})
export default Verify;

View File

@@ -47,10 +47,6 @@ function Sidebar({
}
}, [sidebarExpanded]);
function saveDigitalId () {
localStorage.setItem('digitalId', '7234ABC3423423523457234ABC34234')
}
return (
<div>
{/* Sidebar backdrop (mobile only) */}
@@ -85,7 +81,7 @@ function Sidebar({
</svg>
</button>
{/* Logo */}
<NavLink end to="/" className="block">
<NavLink end to="/dashboard" className="block">
<img alt='logo' src={Logo} width="89" height="32"/>
</NavLink>
</div>
@@ -154,7 +150,7 @@ function Sidebar({
<li className="mb-1 last:mb-0">
<NavLink
end
to="/"
to="/dashboard"
className={({ isActive }) =>
'block text-slate-400 hover:text-slate-200 transition duration-150 truncate ' + (isActive ? '!text-indigo-500' : '')
}
@@ -340,193 +336,6 @@ function Sidebar({
</li>
</ul>
</div>
{/* More group */}
<div>
<h3 className="text-xs uppercase text-slate-500 font-semibold pl-3">
<span className="hidden lg:block lg:sidebar-expanded:hidden 2xl:hidden text-center w-6" aria-hidden="true">
</span>
<span className="lg:hidden lg:sidebar-expanded:block 2xl:block">More</span>
</h3>
<ul className="mt-3">
{/* Onboarding */}
<SidebarLinkGroup>
{(handleClick, open) => {
return (
<React.Fragment>
<a
href="#0"
className={`block text-slate-200 hover:text-white truncate transition duration-150 ${open && 'hover:text-slate-200'}`}
onClick={(e) => {
e.preventDefault();
sidebarExpanded ? handleClick() : setSidebarExpanded(true);
}}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<svg className="shrink-0 h-6 w-6" viewBox="0 0 24 24">
<path
className="fill-current text-slate-600"
d="M19 5h1v14h-2V7.414L5.707 19.707 5 19H4V5h2v11.586L18.293 4.293 19 5Z"
/>
<path
className="fill-current text-slate-400"
d="M5 9a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm14 0a4 4 0 1 1 0-8 4 4 0 0 1 0 8ZM5 23a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm14 0a4 4 0 1 1 0-8 4 4 0 0 1 0 8Z"
/>
</svg>
<span className="text-sm font-medium ml-3 lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Onboarding
</span>
</div>
{/* Icon */}
<div className="flex shrink-0 ml-2">
<svg
className={`w-3 h-3 shrink-0 ml-1 fill-current text-slate-400 ${open && 'transform rotate-180'}`}
viewBox="0 0 12 12"
>
<path d="M5.9 11.4L.5 6l1.4-1.4 4 4 4-4L11.3 6z" />
</svg>
</div>
</div>
</a>
<div className="lg:hidden lg:sidebar-expanded:block 2xl:block">
<ul className={`pl-9 mt-1 ${!open && 'hidden'}`}>
<li className="mb-1 last:mb-0">
<NavLink end to="/onboarding-1" className="block text-slate-400 hover:text-slate-200 transition duration-150 truncate">
<span className="text-sm font-medium lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Step 1
</span>
</NavLink>
</li>
<li className="mb-1 last:mb-0">
<NavLink end to="/onboarding-2" className="block text-slate-400 hover:text-slate-200 transition duration-150 truncate">
<span className="text-sm font-medium lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Step 2
</span>
</NavLink>
</li>
<li className="mb-1 last:mb-0">
<NavLink end to="/onboarding-3" className="block text-slate-400 hover:text-slate-200 transition duration-150 truncate">
<span className="text-sm font-medium lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Step 3
</span>
</NavLink>
</li>
<li className="mb-1 last:mb-0">
<NavLink end to="/onboarding-4" className="block text-slate-400 hover:text-slate-200 transition duration-150 truncate">
<span className="text-sm font-medium lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Step 4
</span>
</NavLink>
</li>
<li className="mb-1 last:mb-0">
<NavLink onClick={()=>saveDigitalId()} end to="/shared-data" className="block text-slate-400 hover:text-slate-200 transition duration-150 truncate">
<span className="text-sm font-medium lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Shared Data
</span>
</NavLink>
</li>
</ul>
</div>
</React.Fragment>
);
}}
</SidebarLinkGroup>
{/* Components */}
<SidebarLinkGroup activecondition={pathname.includes('component')}>
{(handleClick, open) => {
return (
<React.Fragment>
<a
href="#0"
className={`block text-slate-200 hover:text-white truncate transition duration-150 ${
pathname.includes('component') && 'hover:text-slate-200'
}`}
onClick={(e) => {
e.preventDefault();
sidebarExpanded ? handleClick() : setSidebarExpanded(true);
}}
>
<div className="flex items-center justify-between">
<div className="flex items-center">
<svg className="shrink-0 h-6 w-6" viewBox="0 0 24 24">
<circle
className={`fill-current text-slate-600 ${pathname.includes('component') && 'text-indigo-500'}`}
cx="16"
cy="8"
r="8"
/>
<circle
className={`fill-current text-slate-400 ${pathname.includes('component') && 'text-indigo-300'}`}
cx="8"
cy="16"
r="8"
/>
</svg>
<span className="text-sm font-medium ml-3 lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Components
</span>
</div>
{/* Icon */}
<div className="flex shrink-0 ml-2">
<svg
className={`w-3 h-3 shrink-0 ml-1 fill-current text-slate-400 ${open && 'transform rotate-180'}`}
viewBox="0 0 12 12"
>
<path d="M5.9 11.4L.5 6l1.4-1.4 4 4 4-4L11.3 6z" />
</svg>
</div>
</div>
</a>
<div className="lg:hidden lg:sidebar-expanded:block 2xl:block">
<ul className={`pl-9 mt-1 ${!open && 'hidden'}`}>
<li className="mb-1 last:mb-0">
<NavLink
end
to="/component/button"
className={({ isActive }) =>
'block text-slate-400 hover:text-slate-200 transition duration-150 truncate ' + (isActive ? '!text-indigo-500' : '')
}
>
<span className="text-sm font-medium lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Button
</span>
</NavLink>
</li>
<li className="mb-1 last:mb-0">
<NavLink
end
to="/component/badge"
className={({ isActive }) =>
'block text-slate-400 hover:text-slate-200 transition duration-150 truncate ' + (isActive ? '!text-indigo-500' : '')
}
>
<span className="text-sm font-medium lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Badge
</span>
</NavLink>
</li>
<li className="mb-1 last:mb-0">
<NavLink
end
to="/component/accordion"
className={({ isActive }) =>
'block text-slate-400 hover:text-slate-200 transition duration-150 truncate ' + (isActive ? '!text-indigo-500' : '')
}
>
<span className="text-sm font-medium lg:opacity-0 lg:sidebar-expanded:opacity-100 2xl:opacity-100 duration-200">
Accordion
</span>
</NavLink>
</li>
</ul>
</div>
</React.Fragment>
);
}}
</SidebarLinkGroup>
</ul>
</div>
</div>
{/* Expand / collapse button */}

View File

@@ -1,108 +0,0 @@
import React, {useState, useEffect} from 'react';
import ProfileTableItem from './ProfileTableItem';
function ProfileTable({
selectedItems,
userData
}) {
const [isCheck, setIsCheck] = useState([]);
useEffect(() => {
selectedItems(isCheck);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isCheck]);
const handleClick = e => {
const { id, checked } = e.target;
setIsCheck([...isCheck, id]);
if (!checked) {
setIsCheck(isCheck.filter(item => item !== id));
}
};
return (
<>
{/* General */}
<h2 className="grow text-base font-semibold text-slate-800 truncate mb-2.5 mt-8">General 🖋</h2>
<div className="overflow-x-auto w-[828px]">
<table className="w-[828px] table-auto w-full">
<tbody className="divide-slate-200 divide-y">
{userData.filter(data => data.category === 'General')
.map(data => {
return (
<ProfileTableItem
key={data.id}
id={data.id}
image={data.image}
value={data.value}
property={data.property}
status={data.status}
transactions={data.transactions}
avatars={data.avatars}
handleClick={handleClick}
isChecked={isCheck.includes(data.id)}
/>
)
})
}
</tbody>
</table>
</div>
{/* Nationality */}
<h2 className="grow text-base font-semibold text-slate-800 truncate mb-2.5 mt-8">Nationality 🖋</h2>
<div className="overflow-x-auto w-[828px]">
<table className="w-[828px] table-auto w-full">
<tbody className="text-sm divide-slate-200 divide-y ">
{userData.filter(data => data.category === 'Nationality')
.map(data => {
return (
<ProfileTableItem
key={data.id}
id={data.id}
image={data.image}
value={data.value}
property={data.property}
status={data.status}
transactions={data.transactions}
avatars={data.avatars}
handleClick={handleClick}
isChecked={isCheck.includes(data.id)}
/>
)
})
}
</tbody>
</table>
</div>
{/* Social */}
<h2 className="grow text-base font-semibold text-slate-800 truncate mb-2.5 mt-8">Social 🖋</h2>
<div className="overflow-x-auto w-[828px]">
<table className="w-[828px] table-auto w-full">
<tbody className="text-sm divide-slate-200 divide-y ">
{userData.filter(data => data.category === 'Social')
.map(data => {
return (
<ProfileTableItem
key={data.id}
id={data.id}
image={data.image}
value={data.value}
property={data.property}
status={data.status}
transactions={data.transactions}
avatars={data.avatars}
handleClick={handleClick}
isChecked={isCheck.includes(data.id)}
/>
)
})
}
</tbody>
</table>
</div>
</>
)
}
export default ProfileTable;

View File

@@ -0,0 +1,140 @@
import React, {useState, useEffect} from 'react';
import ProfileTableItem from './ProfileTableItem';
import ProfileIcon from '../../images/profile-icon.svg';
function ProfileTable({
userData,
handleClick,
isCheck,
}) {
const defaultData = {
image: ProfileIcon,
status: 'Stored',
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
avatars: null
};
const data = {
general:["First name","Second name", "Gender", "Birthdate", "Place of birth"],
nationality:["Nationality", "National ID", "National doctype", "National doc ID", "National doc issue date", "National doc expiry date"],
social:["Telephone", "Twitter", "Facebook", "Instagram", "Youtube", "Wechat", "Tiktok", "Linkedin", "Vk", "Github", "Telegram", "Qq", "Snapchat", "Reddit"]
}
const generalData = userData.filter(elem => data.general.includes(elem.label));
const nationalityData = userData.filter(elem => data.nationality.includes(elem.label));
const sosialData = userData.filter(elem => data.social.includes(elem.label));
const otherData = userData.filter((elem) =>
!data.general.includes(elem.label) && !data.nationality.includes(elem.label) && !data.social.includes(elem.label));
return (
<>
{/* General */}
<div className={`${generalData.length > 0 || 'hidden'}`}>
<h2 className="grow text-base font-semibold text-slate-800 truncate mb-2.5 mt-8">General 🖋</h2>
<div className="overflow-x-auto w-[828px]">
<table className="w-[828px] table-auto w-full">
<tbody className="divide-slate-200 divide-y">
{generalData.map((data) => {
return (
<ProfileTableItem
key={data.label}
id={data.key}
image={defaultData.image}
value={data.value.charAt(0).toUpperCase()+data.value.slice(1)}
property={data.label}
status={defaultData.status}
transactions={defaultData.transactions}
avatars={defaultData.avatars}
handleClick={handleClick}
isChecked={isCheck.includes(data.key)}
/>
)
})}
</tbody>
</table>
</div>
</div>
{/* Nationality */}
<div className={`${nationalityData.length > 0 || 'hidden'}`}>
<h2 className="grow text-base font-semibold text-slate-800 truncate mb-2.5 mt-8">Nationality 🖋</h2>
<div className="overflow-x-auto w-[828px]">
<table className="w-[828px] table-auto w-full">
<tbody className="text-sm divide-slate-200 divide-y ">
{nationalityData.map(data => {
return (
<ProfileTableItem
key={data.label}
id={data.key}
image={defaultData.image}
value={data.value.charAt(0).toUpperCase()+data.value.slice(1)}
property={data.label}
status={defaultData.status}
transactions={defaultData.transactions}
avatars={defaultData.avatars}
handleClick={handleClick}
isChecked={isCheck.includes(data.key)}
/>
)
})}
</tbody>
</table>
</div>
</div>
{/* Social */}
<div className={`${sosialData.length > 0 || 'hidden'}`}>
<h2 className="grow text-base font-semibold text-slate-800 truncate mb-2.5 mt-8">Social 🖋</h2>
<div className="overflow-x-auto w-[828px]">
<table className="w-[828px] table-auto w-full">
<tbody className="text-sm divide-slate-200 divide-y ">
{sosialData.map(data => {
return (
<ProfileTableItem
key={data.label}
id={data.key}
image={defaultData.image}
value={data.value.charAt(0).toUpperCase()+data.value.slice(1)}
property={data.label}
status={defaultData.status}
transactions={defaultData.transactions}
avatars={defaultData.avatars}
handleClick={handleClick}
isChecked={isCheck.includes(data.key)}
/>
)
})}
</tbody>
</table>
</div>
</div>
{/* Other */}
<div className={`${otherData.length > 0 || 'hidden'}`}>
<h2 className="grow text-base font-semibold text-slate-800 truncate mb-2.5 mt-8">Other 🖋</h2>
<div className="overflow-x-auto w-[828px]">
<table className="w-[828px] table-auto w-full">
<tbody className="text-sm divide-slate-200 divide-y ">
{otherData.map(data => {
return (
<ProfileTableItem
key={data.key}
id={data.key}
image={defaultData.image}
value={data.value}
property={data.label}
status={defaultData.status}
transactions={defaultData.transactions}
avatars={defaultData.avatars}
handleClick={handleClick}
isChecked={isCheck.includes(data.key)}
/>
)
})}
</tbody>
</table>
</div>
</div>
</>
)
}
export default ProfileTable;

View File

@@ -90,7 +90,7 @@ function ProfileTableItem(props) {
</td>
</tr>
<tr className={`${!descriptionOpen && 'hidden'} ${props.status !== 'Progress' || 'bg-[#eaf0f6]'}` }>
<td colSpan="10" className="px-12 py-3.5">
<td colSpan="10" className="px-12 pt-3.5 pb-[14px]">
<div className="flex items-center gap-x-5">
<div>
<label className="block text-sm font-medium mb-1" htmlFor="placeholder">Seed</label>
@@ -102,7 +102,7 @@ function ProfileTableItem(props) {
</div>
</div>
{/* Progress validation bar */}
<div className="pt-[18px] pb-8">
<div className="pt-[18px]">
<div className="h-full max-w-md w-full flex flex-row">
<div className="w-32 shrink-0">
<h2 className="text-xl leading-snug font-bold text-slate-800 xl:leading-7 mb-4 xl:mb-0">Today</h2>

View File

@@ -1,6 +1,6 @@
import React from "react";
import ValidationUsersImg from "../validationlog/ValidationUsersImg";
import ValidationUsersImg from "../validationLog/ValidationUsersImg";
function SharedDataRoadMap({ data }) {

View File

@@ -19,8 +19,8 @@ function ValidateTableItem(props) {
}
return (
<tr className="hover:bg-[#E2E8F0] cursor-pointer" onClick={(e) => openValidatePanel(e)}>
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap w-px">
<tr className="hover:bg-[#eaf0f6] cursor-pointer" onClick={(e) => openValidatePanel(e)}>
<td className="px-2 first:pl-4 last:pr-5 py-3 whitespace-nowrap w-px">
<div className="flex items-center">
<label className="inline-flex">
<span className="sr-only">Select</span>

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useRef } from 'react';
import React from 'react';
import Image from '../../images/transactions-image-04.svg';
@@ -7,38 +7,13 @@ function TransactionPanel({
setValidatePanelOpen
}) {
const closeBtn = useRef(null);
const panelContent = useRef(null);
// close on click outside
useEffect(() => {
const clickHandler = ({ target }) => {
if (!validatePanelOpen || panelContent.current.contains(target) || closeBtn.current.contains(target)) return;
setValidatePanelOpen(false);
};
document.addEventListener('click', clickHandler);
return () => document.removeEventListener('click', clickHandler);
});
// close if the esc key is pressed
useEffect(() => {
const keyHandler = ({ keyCode }) => {
if (!validatePanelOpen || keyCode !== 27) return;
setValidatePanelOpen(false);
};
document.addEventListener('keydown', keyHandler);
return () => document.removeEventListener('keydown', keyHandler);
});
return (
<div
ref={panelContent}
className={`absolute inset-0 sm:left-auto z-20 transition-transform duration-200 ease-in-out ${
validatePanelOpen ? 'translate-x-' : 'translate-x-full'
}`}>
<div className="sticky top-16 bg-gradient-to-b from-[#E2E8F0] via-slate-100 to-white overflow-x-hidden overflow-y-auto no-scrollbar shrink-0 border-l border-slate-200 w-full sm:w-[390px] h-[calc(100vh-64px)]">
<div className="top-16 bg-gradient-to-b from-[#e4eaf0] to-white shrink-0 border-l border-slate-200 w-full sm:w-[390px] h-fit">
<button
ref={closeBtn}
onClick={() => setValidatePanelOpen(false)}
className="absolute top-0 right-0 mt-6 mr-6 group p-2"
>
@@ -83,38 +58,38 @@ function TransactionPanel({
<span className="font-medium text-slate-700 text-right">IT17 2207 1010 0504 0006 88</span>
</div>
<div className="flex justify-between space-x-1">
<span className="italic">Transacion::</span>
<span className="italic">Transaction:</span>
<span className="font-medium text-slate-700 text-right">145 bytes</span>
</div>
</div>
</div>
{/* Receipts */}
<div className="mt-6">
<div className="text-sm font-semibold text-slate-800 mb-2">Receipts</div>
<form className="rounded bg-slate-100 border border-dashed border-slate-300 text-center px-5 py-8">
<div className="text-sm font-medium text-slate-800 mb-2">Private Data</div>
<form className="rounded bg-slate-50 border border-dashed border-slate-300 text-center px-5 py-8">
<svg className="inline-flex w-4 h-4 fill-slate-400 mb-3" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="M8 4c-.3 0-.5.1-.7.3L1.6 10 3 11.4l4-4V16h2V7.4l4 4 1.4-1.4-5.7-5.7C8.5 4.1 8.3 4 8 4ZM1 2h14V0H1v2Z" />
</svg>
<label htmlFor="upload" className="block text-sm text-slate-500 italic">Upload exported JSON data</label>
<label htmlFor="upload" className="block text-sm text-slate-400 italic">Upload exported JSON data</label>
<input className="sr-only" id="upload" type="file" />
</form>
</div>
{/* Notes */}
<div className="mt-6">
<div className="text-sm font-semibold text-slate-800 mb-2">Notes</div>
<div className="text-sm font-medium text-slate-800 mb-2">Notes</div>
<form>
<label className="sr-only" htmlFor="notes">Write a note</label>
<textarea id="notes" className="form-textarea w-full focus:border-slate-300" rows="4" placeholder="Write a note…" defaultValue={""} />
<textarea id="notes" className="resize-none form-textarea w-full focus:border-slate-300" rows="4" placeholder="Write a note…" defaultValue={""} />
</form>
</div>
{/* Download / Report */}
<div className="flex items-center space-x-3 mt-6">
<div className="flex items-center space-x-3 mt-[84px]">
<div className="w-1/2">
<button className="btn w-full border-slate-200 hover:border-slate-300 text-slate-600">
<svg className="w-4 h-4 fill-current text-slate-400 shrink-0 rotate-180" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="M8 4c-.3 0-.5.1-.7.3L1.6 10 3 11.4l4-4V16h2V7.4l4 4 1.4-1.4-5.7-5.7C8.5 4.1 8.3 4 8 4ZM1 2h14V0H1v2Z" />
</svg>
<span className="ml-2">Validate</span>
<span className="ml-2 text-sm font-medium">Validate</span>
</button>
</div>
<div className="w-1/2">
@@ -122,7 +97,7 @@ function TransactionPanel({
<svg className="w-4 h-4 fill-current shrink-0" viewBox="0 0 16 16">
<path d="M7.001 3h2v4h-2V3Zm1 7a1 1 0 1 1 0-2 1 1 0 0 1 0 2ZM15 16a1 1 0 0 1-.6-.2L10.667 13H1a1 1 0 0 1-1-1V1a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1ZM2 11h9a1 1 0 0 1 .6.2L14 13V2H2v9Z" />
</svg>
<span className="ml-2">Invalidate</span>
<span className="ml-2 text-sm font-medium">Invalidate</span>
</button>
</div>
</div>

View File

@@ -83,7 +83,7 @@ function ValidateTable({
{/* Table header */}
<thead className="bg-white text-xs font-semibold uppercase text-slate-500 border-t border-b-2 border-slate-200">
<tr>
<th className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap w-px">
<th className="first:pl-4 last:pr-5 py-3 whitespace-nowrap w-px">
<div className="flex items-center">
<label className="inline-flex">
<span className="sr-only">Select all</span>

View File

@@ -6,18 +6,18 @@ import ValidationUsersImg from "./ValidationUsersImg";
function ValidateRoadMap({ season }) {
return (
<article className="pt-6">
<article className="pt-3">
<div className="xl:flex">
<div className="w-32 shrink-0">
<h2 className="text-xl leading-snug font-bold text-slate-800 xl:leading-7 mb-4 xl:mb-0">{season.name}</h2>
<h2 className="text-xl leading-snug font-bold text-slate-800 xl:leading-7 mb-4 xl:mb-0">{''}</h2>
</div>
<div className="grow pb-6 border-b border-slate-200">
<header>
<div className="flex flex-nowrap items-center space-x-2 mb-6">
{/* Avatars */}
<div className="flex shrink-0 -space-x-3 -ml-px">
{season.usersImges.map(pic => {
return <ValidationUsersImg key={pic.imgId} image={pic}/>
{season.users_images.map(pic => {
return <ValidationUsersImg image={pic} key={pic.image}/>
})}
</div>
<div className="text-slate-400">·</div>
@@ -26,8 +26,8 @@ function ValidateRoadMap({ season }) {
{/* List */}
<ul className="-my-2">
{/* List item(s) */}
{season.items.map((item, index) => {
return <ValidationSeasonItem key={item.id} length={season.items.length} item={item} index={index}/>
{season.transaction.map((item, index) => {
return <ValidationSeasonItem key={item.label} length={season.transaction.length} item={item} index={index}/>
})}
</ul>
</div>

View File

@@ -2,25 +2,25 @@ import React from "react";
function ValidationSeasonItem({ length, item, index }) {
return (
<li className="relative py-2">
<div className="flex items-center mb-1">
<li className="relative pt-2 pb-2.5">
<div className="flex items-center mb-2.5">
{length-1!==index && <div className="absolute left-0 h-full w-0.5 bg-slate-200 self-start ml-2.5 -translate-x-1/2 translate-y-3" aria-hidden="true"></div>}
<div className={`absolute left-0 rounded-full ${item.checked ? "bg-indigo-500" : "bg-[#FF0000]"}`} aria-hidden="true">
<div className={`${item.address ? "bg-indigo-500" : "bg-[#FF0000]"} absolute left-0 rounded-full`} aria-hidden="true">
<svg className="w-5 h-5 fill-current text-white" viewBox="0 0 20 20">
{item.checked && <path d="M14.4 8.4L13 7l-4 4-2-2-1.4 1.4L9 13.8z"/>}
{item.address && <path d="M14.4 8.4L13 7l-4 4-2-2-1.4 1.4L9 13.8z"/>}
</svg>
</div>
<h3 className="text-lg font-bold text-slate-800 pl-9">
{item.text} {item.checked && <a className="cursor-pointer font-bold text-indigo-500 hover:text-indigo-600 underline hover:no-underline" >{`0x${item.dataSeason}`}</a>}
{`${item.label} ${item.address ? "by" : "Updated"}`} <a className="cursor-pointer font-bold text-indigo-500 hover:text-indigo-600 underline hover:no-underline" >{item.address}</a>
</h3>
</div>
<div className="block text-slate-800 w-fit pl-9">
<div className="text-base font-semibold underline mb-[-10px]">{`0x${item.dataSeason}`}</div>
<span className="font-normal text-[10px]">Transactions ID</span>
<div className="text-base font-semibold underline mb-[-10px]">{item.transaction_id}</div>
<span className="font-normal text-slate-600 text-[10px]">Transactions ID</span>
</div>
<div className="mb-3.5 block text-slate-800 w-fit pl-9">
<div className="text-base font-semibold underline mb-[-10px]">{item.dataSeason}</div>
<span className="font-normal text-[10px]">Validated data</span>
<div className="text-base font-semibold underline mb-[-10px]">{item.value}</div>
<span className={`${!item.value && "hidden"} font-normal text-slate-600 text-[10px]`}>{item.address ? "Validated data" : "Updated data"}</span>
</div>
<a className="cursor-pointer pl-9 font-normal text-sm text-indigo-500 hover:text-indigo-600">Explore -&gt;</a>
</li>

View File

@@ -1,9 +1,10 @@
import React from "react";
function ValidationUsersImg({ image }) {
return (
<a className="block" href="#0">
<img className="rounded-full border-2 border-slate-100 box-content" src={image.img} width={`${image.size}`} alt={image.img} height={`${image.size}`}/>
<a className="block">
<img className="rounded-full border-2 border-slate-100 box-content" src={image.image} width={`${image.size}`} alt={image.image} height={`${image.size}`}/>
</a>
);
}

103
src/shared/fetchWrapper.js Normal file
View File

@@ -0,0 +1,103 @@
import {registrationStore} from '../store/store';
function prepareUrl(url) {
if (url.startsWith('http')) return url;
return `${window.location.origin}/api/${url}`;
}
function handleRequest(method, url, headers, attempts, token, body) {
return new Promise((resolve, reject) => {
(function internalRequest() {
return request(method, url, headers, token, body)
.then(resolve)
.catch(err => --attempts > 0 ? internalRequest() : reject(err))
})()
})
.then((res) => res.json())
.catch(() => [])
};
/**
* Request
* @param {string} method - method name
* @param {string} url - endpoint url.
* @param {string} token - auth token
* @param {object} body - request body.
* @param {object} headers - request headers
*/
function request(method, url, headers = {}, token, body) {
let controller = new AbortController;
let requestOptions = {};
if (method === 'GET' || method === 'DELETE'){
requestOptions = {
method: method,
headers: {
Authorization: `IDNTTY ${token}`,
...headers
},
signal: controller.signal,
}
};
if (method === 'POST' || method === 'PUT'){
requestOptions = {
method: method,
headers: {
Authorization: `IDNTTY ${token}`,
Accept: 'application/json',
'Content-Type': 'application/json',
...headers
},
body: JSON.stringify(body),
signal: controller.signal,
}
};
if (!token) {
requestOptions.headers.Authorization = null;
}
setTimeout(() => controller.abort(), 3000);
return fetch(prepareUrl(url), requestOptions);
};
function get(url, headers, attempts = 1) {
return handleRequest('GET', url, headers, attempts, null);
}
function getAuth(url, headers, attempts = 1) {
return handleRequest('GET', url, headers, attempts, registrationStore.tokenKey);
}
function del(url, headers, attempts = 1) {
return handleRequest('DELETE', url, headers, attempts, null);
}
function delAuth(url, headers, attempts = 1) {
return handleRequest('DELETE', url, headers, attempts, registrationStore.tokenKey);
}
function post(url, headers, body, attempts = 1) {
return handleRequest('POST', url, headers, attempts, null, body);
}
function postAuth(url, headers, body, attempts = 1) {
return handleRequest('POST', url, headers, attempts, registrationStore.tokenKey, body);
}
function put(url, headers, body, attempts = 1) {
return handleRequest('PUT', url, headers, attempts, null, body);
}
function putAuth(url, headers, body, attempts = 1) {
return handleRequest('PUT', url, headers, attempts, registrationStore.tokenKey, body);
}
export const fetchWrapper = {
get,
del,
post,
put,
getAuth,
delAuth,
postAuth,
putAuth,
baseUrl: ''
};

27
src/shared/labelMap.js Normal file
View File

@@ -0,0 +1,27 @@
export const labelMap = {
firstname: 'First name',
secondname: 'Second name',
gender: "Gender",
birthdate: "Birthdate",
placeofbirth: "Place of birth",
nationality: "Nationality",
nationalid: "National ID",
nationaldoctype: "National doctype",
nationaldocid: "National doc ID",
nationaldocissuedate: "National doc issue date",
nationaldocexpirydate: "National doc expiry date",
telephone: "Telephone",
twitter: "Twitter",
facebook: "Facebook",
instagram: "Instagram",
youtube: "Youtube",
wechat: "Wechat",
tiktok: "Tiktok",
linkedin: "Linkedin",
vk: "Vk",
github: "Github",
telegram: "Telegram",
qq: "Qq",
snapchat: "Snapchat",
reddit: "Reddit",
};

231
src/store/store.js Normal file
View File

@@ -0,0 +1,231 @@
import { reaction, makeAutoObservable, onBecomeObserved, onBecomeUnobserved} from "mobx";
import {cryptography} from "@liskhq/lisk-client";
import { passphrase } from "@liskhq/lisk-client";
import {getNodeInfo} from '../api/node';
import {fetchWrapper} from '../shared/fetchWrapper';
import {labelMap} from "../shared/labelMap";
import User08 from "../images/user-28-08.jpg";
import User06 from "../images/user-28-06.jpg";
import User05 from "../images/user-28-05.jpg";
import User09 from "../images/user-28-09.jpg";
const usersImages = [User08,User06,User05,User09];
class Store {
_accountData = []
_passPhrase
_nodeInfo = {}
_keysArray = []
_sharedData = []
_transactionsInfo = []
constructor() {
makeAutoObservable(this, {});
this.fetchNodeInfo()
reaction(() => this.keysArray, () => this.fetchSharedData())
onBecomeObserved(this, "decryptedAccountData", () => this.fetchNewAccountData())
onBecomeObserved(this, "sharedData", () => this.fetchKeysArray())
onBecomeUnobserved(this, "sharedData", () => this.unobservedSharedData())
onBecomeObserved(this, "transactionsInfo", () => this.fetchTransactionsInfo())
onBecomeUnobserved(this, "transactionsInfo", () => this.unobservedTransactionsInfo())
};
fetchNewAccountData() {
getNodeInfo()
.then((info)=>{
this.fetchNodeInfoSuccess(info)
fetchWrapper.getAuth('data/private', {
networkIdentifier: this.nodeInfo.networkIdentifier,
lastBlockID: this.nodeInfo.lastBlockID
}).then((res) => this.accountDataFetchChange(res))
})
.catch((err) => this.fetchNodeInfoFailed(err))
}
pushAccountData(data = this.accountData) {
fetchWrapper.postAuth('data/private', {
networkIdentifier: this.nodeInfo.networkIdentifier,
lastBlockID: this.nodeInfo.lastBlockID
}, [...this.encryptAccountData(data)])
.then(() => this.fetchNewAccountData())
}
fetchKeysArray() {
getNodeInfo()
.then((info)=>{
this.fetchNodeInfoSuccess(info)
fetchWrapper.getAuth('data/shared/', {
networkIdentifier: this.nodeInfo.networkIdentifier,
lastBlockID: this.nodeInfo.lastBlockID
}).then((res) => this.keysArrayFetchChange(res))
})
.catch((err) => this.fetchNodeInfoFailed(err))
}
fetchTransactionsInfo() {
fetchWrapper.get("account/transactions/71ccaeefe22050abc9b36ce0c1744316c11c49e1", {
networkIdentifier: this.nodeInfo.networkIdentifier,
lastBlockID: this.nodeInfo.lastBlockID
}).then((res) => this.saveInfoTransactions(res))
};
generatePassPhrase() {
this._passPhrase = passphrase.Mnemonic.generateMnemonic();
sessionStorage.setItem('passPhrase', this._passPhrase);
};
fetchSharedData() {
this._keysArray.forEach((elem) => fetchWrapper.get(`data/shared/${elem}`).then((res) => this.changeSharedData(res)))
};
unobservedTransactionsInfo() {
this._transactionsInfo = []
};
unobservedSharedData() {
this._sharedData = []
};
changeSharedData(incomingData) {
this._sharedData.push({
data: incomingData.data,
})
}
savePastPassPhrase(phrase) {
this._passPhrase = phrase;
sessionStorage.setItem('passPhrase', this._passPhrase);
};
saveDataRegistration(data) {
this._accountData = data;
};
fetchNodeInfo() {
getNodeInfo()
.then((info)=>this.fetchNodeInfoSuccess(info))
.catch((err) => this.fetchNodeInfoFailed(err))
}
saveInfoTransactions(transaction) {
this._transactionsInfo = transaction.data
}
accountDataFetchChange(res) {
if (res.data) {
this._accountData = res.data;
}
};
keysArrayFetchChange(res) {
this._keysArray = res.data;
}
fetchNodeInfoSuccess(info) {
this._nodeInfo = info.data;
}
fetchNodeInfoFailed(err) {
console.log(err);
}
get sharedData() {
return this._sharedData.map(elem => ({
data: elem.data.map(item => ({
label: labelMap[item.label],
value: item.value,
}))
}));
};
get transactionsInfo() {
return this._transactionsInfo.map(item => {
return {
id: item.id,
users_images: usersImages.map(image => {
return {
image: image,
size: 24
}
}),
transaction: item.asset.features.map(asset => {
return {
transaction_id: item.id,
address: item.asset.recipientAddress && cryptography.bufferToHex(cryptography.getAddressFromPublicKey(cryptography.hexToBuffer(item.senderPublicKey))),
value: asset.value,
label: labelMap[asset.label],
}
})
}
})
}
get decryptedAccountData() {
return this._accountData.map((elem) => ({
...elem,
key: elem.label,
label: labelMap[elem.label],
value: cryptography.decryptMessageWithPassphrase(elem.value, elem.value_nonce, this.passPhrase, this.pubKey).split(':')[1]
}))
}
encryptAccountData(data) {
return data.map((item) => {
let value = cryptography.encryptMessageWithPassphrase(cryptography.getRandomBytes(32).toString('hex') + ":" + item.value, this.passPhrase, this.pubKey);
return {
label: item.key,
value: value.encryptedMessage,
value_nonce: value.nonce,
seed: item.seed,
}
})
}
get keysArray() {
return this._keysArray;
}
get passPhrase() {
if(sessionStorage.getItem('passPhrase')) {
this._passPhrase = sessionStorage.getItem('passPhrase')
}
return this._passPhrase
}
get accountData() {
return this._accountData
};
get nodeInfo() {
return this._nodeInfo;
}
get addressAndPubKey() {
return cryptography.getAddressAndPublicKeyFromPassphrase(this.passPhrase);
}
get pubKey() {
return this.addressAndPubKey.publicKey.toString('hex');
}
get address() {
return this.addressAndPubKey.address.toString('hex')
}
get tokenKey() {
const stringToSign = this.nodeInfo.networkIdentifier + this.nodeInfo.lastBlockID;
if(!stringToSign)
return '';
const sign = cryptography.signDataWithPassphrase(Buffer.from(stringToSign, 'hex'), this.passPhrase).toString('hex')
return this.pubKey + ':' +sign
}
};
export const registrationStore = new Store();

View File

@@ -17,7 +17,7 @@ module.exports = {
blue: '2px solid rgba(0, 112, 244, 0.5)',
},
fontFamily: {
inter: ['Inter', 'sans-serif'],
sans: ['Inter', 'sans-serif'],
},
fontSize: {
descriptionSize: ['0.75rem', { lineHeight: '1.25' }],

View File

@@ -2,7 +2,7 @@ import resolveConfig from 'tailwindcss/resolveConfig';
export const tailwindConfig = () => {
// Tailwind config
return resolveConfig('./src/css/tailwind.config.js')
return resolveConfig('./src/tailwind.config.js')
}
export const hexToRGB = (h) => {

View File

@@ -1,29 +0,0 @@
import { defineConfig } from 'vite'
import postcss from './postcss.config.js'
import react from '@vitejs/plugin-react'
// https://vitejs.dev/config/
export default defineConfig({
define: {
'process.env': process.env
},
css: {
postcss,
},
plugins: [react()],
resolve: {
alias: [
{
find: /^~.+/,
replacement: (val) => {
return val.replace(/^~/, "");
},
},
],
},
build: {
commonjsOptions: {
transformMixedEsModules: true,
}
}
})

98
webpack.config.js Normal file
View File

@@ -0,0 +1,98 @@
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const plugins = [
new HtmlWebpackPlugin({
favicon: './public/favicon.ico',
template: './public/index.html',
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
new webpack.ProvidePlugin({
process: 'process/browser',
}),
require('tailwindcss')
];
module.exports = {
entry: './src/main.jsx',
mode: 'development',
devtool: 'eval-source-map',
plugins,
output: {
clean: true,
path: path.resolve(__dirname, 'build'),
assetModuleFilename: 'assets/[hash][ext]',
filename: 'main.[hash:8].js',
},
devServer: {
open: true,
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 'auto',
hot: true,
client: {
progress: true,
},
proxy: {
'/api/**': {
target: 'http://3.125.47.101',
secure: false,
changeOrigin: true
}
}
},
module: {
rules: [
{ test: /\.(html)$/, use: ['html-loader'] },
{
test: /\.m?jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.scss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ["file-loader"]
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
fallback: {
"path": require.resolve("path-browserify"),
"os": require.resolve("os-browserify/browser"),
"querystring": require.resolve("querystring-es3"),
"crypto": require.resolve("crypto-browserify"),
"util": require.resolve("util/"),
"stream": require.resolve("stream-browserify"),
"url": require.resolve("url/"),
"buffer": require.resolve("buffer/"),
"fs": false
}
},
};