Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9820692cd9 | ||
|
|
5eb4ee16c0 | ||
|
|
bc364d1b85 | ||
|
|
8489bc375c | ||
|
|
7ad29e8fe0 | ||
|
|
0fb5764a70 | ||
|
|
5ebc965a2a | ||
|
|
138047fa10 | ||
|
|
a271da7bf9 | ||
|
|
79784cbcee | ||
|
|
596c44aac3 | ||
|
|
5d17137815 | ||
|
|
18bf373508 | ||
|
|
944c9989e9 | ||
|
|
202989f374 | ||
|
|
f21d10f830 | ||
|
|
c8604a56ac | ||
|
|
2d0ae35cc8 | ||
|
|
76f942b90f | ||
|
|
f0e0d9479d | ||
|
|
3403289e0a | ||
|
|
25fddec6e8 | ||
|
|
1d0cb45024 | ||
|
|
222850dfd9 | ||
|
|
8f225752cf | ||
|
|
038657751a | ||
|
|
29d7d6fdb8 | ||
|
|
e44dfee284 | ||
|
|
0f455f126d | ||
|
|
0d4f27660a | ||
|
|
9703371f28 | ||
|
|
16ca8a1df2 | ||
|
|
e883b190a7 | ||
|
|
85897a8efe | ||
|
|
5f85d1696a | ||
|
|
1c539e5255 | ||
|
|
bcfc018560 | ||
|
|
e175ca0295 | ||
|
|
bac246eac2 | ||
|
|
f65c99e86a | ||
|
|
63439b2da1 | ||
|
|
1d9368d200 | ||
|
|
3a4ed9daf9 | ||
|
|
54ccd3ed9f | ||
|
|
fe1105e9d6 | ||
|
|
95cc2ac1e0 | ||
|
|
b4516ef18e | ||
|
|
d617de75b5 | ||
|
|
83e5e39d3c |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
# dependencies
|
||||
/node_modules
|
||||
.idea
|
||||
15
Dockerfile
Normal file
15
Dockerfile
Normal 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
|
||||
33
deploy/nginx.conf
Normal file
33
deploy/nginx.conf
Normal 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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
|
||||
import {
|
||||
Routes,
|
||||
Route,
|
||||
useLocation
|
||||
useLocation,
|
||||
} from 'react-router-dom';
|
||||
|
||||
import './css/style.scss';
|
||||
|
||||
3
src/api/node.js
Normal file
3
src/api/node.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import {fetchWrapper} from '../shared/fetchWrapper';
|
||||
|
||||
export const getNodeInfo = (headers) => fetchWrapper.get('node/info/', headers)
|
||||
@@ -2,7 +2,7 @@ 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/registrationStore";
|
||||
import {registrationStore} from "../store/store";
|
||||
import {generateSvgAvatar} from "../images/GenerateOnboardingSvg/GenerateSvg";
|
||||
import UserAvatar from '../images/user-avatar-32.png';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import {Buffer} from "buffer";
|
||||
import { BrowserRouter as Router } from 'react-router-dom'
|
||||
import { HashRouter as Router } from 'react-router-dom'
|
||||
import App from './App'
|
||||
|
||||
globalThis.Buffer = Buffer
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, {useEffect} from 'react';
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import OnboardingImage from '../images/onboarding-image.jpg';
|
||||
@@ -6,14 +6,11 @@ import OnboardingDecoration from '../images/auth-decoration.png';
|
||||
import Logo from "../images/logo.png";
|
||||
import {observer} from "mobx-react-lite";
|
||||
import {passphrase} from "@liskhq/lisk-client";
|
||||
import {registrationStore} from "../store/registrationStore";
|
||||
import {registrationStore} from "../store/store";
|
||||
|
||||
const Onboarding1 = observer(()=>{
|
||||
let phrase = passphrase.Mnemonic.generateMnemonic()
|
||||
registrationStore.savePassPhrase(phrase)
|
||||
useEffect(()=>{
|
||||
|
||||
},[])
|
||||
|
||||
return (
|
||||
<main className="bg-white">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import React, {useState} from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { registrationStore } from "../store/registrationStore";
|
||||
import { registrationStore } from "../store/store";
|
||||
|
||||
import OnboardingImage from '../images/onboarding-image.jpg';
|
||||
import OnboardingDecoration from '../images/auth-decoration.png';
|
||||
@@ -11,9 +11,9 @@ const Onboarding2 = observer(()=>{
|
||||
const [dataRegistration, setDataRegistration] = useState(
|
||||
{
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
second_name: '',
|
||||
gender: '',
|
||||
date_birth: '',
|
||||
birthdate: '',
|
||||
}
|
||||
)
|
||||
const [fillingForm, setFillingForm] = useState(false)
|
||||
@@ -24,31 +24,22 @@ const Onboarding2 = observer(()=>{
|
||||
...dataRegistration,
|
||||
[event.target.id]: newValue
|
||||
})
|
||||
if(!Object.keys(dataRegistration).find(item=>!dataRegistration[item])) {
|
||||
setFillingForm(true)
|
||||
}
|
||||
}
|
||||
|
||||
const saveStoreRegistration = ()=>{
|
||||
Object.keys(dataRegistration).forEach(item=>{
|
||||
let element=document.getElementById(item)
|
||||
if(dataRegistration[item]) {
|
||||
element.style.borderColor=""
|
||||
} else {
|
||||
element.style.borderColor="red"
|
||||
}
|
||||
})
|
||||
if(Object.keys(dataRegistration).find(item=>!dataRegistration[item])) {
|
||||
return
|
||||
} else {
|
||||
setFillingForm(true)
|
||||
if(fillingForm) {
|
||||
registrationStore.saveDataRegistration(Object.keys(dataRegistration).map(item=>{
|
||||
return{
|
||||
key: `${item}`,
|
||||
value: dataRegistration[item]
|
||||
}
|
||||
}))
|
||||
}
|
||||
registrationStore.saveDataRegistration(dataRegistration)
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
if(fillingForm===true) {
|
||||
document.getElementById("signup").click()
|
||||
}
|
||||
},[fillingForm])
|
||||
|
||||
return (
|
||||
<main className="bg-white">
|
||||
|
||||
@@ -107,8 +98,8 @@ const Onboarding2 = observer(()=>{
|
||||
<input id="first_name" onChange={(event)=>saveValueChange(event)} className="form-input w-full" type="text" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1" htmlFor="last_name">Last name <span className="text-rose-500">*</span></label>
|
||||
<input id="last_name" onChange={(event)=>saveValueChange(event)} 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 id="second_name" onChange={(event)=>saveValueChange(event)} className="form-input w-full" type="text" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1" htmlFor="gender">Gender <span className="text-rose-500">*</span></label>
|
||||
@@ -119,8 +110,8 @@ const Onboarding2 = observer(()=>{
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-medium mb-1" htmlFor="date_birth">Date of birth <span className="text-rose-500">*</span></label>
|
||||
<input id="date_birth" onChange={(event)=>saveValueChange(event)} className="form-input w-full" type="date" autoComplete="on" />
|
||||
<label className="block text-sm font-medium mb-1" htmlFor="birthdate">Date of birth <span className="text-rose-500">*</span></label>
|
||||
<input 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">
|
||||
|
||||
@@ -2,23 +2,22 @@ import React, { useState} from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {generateSvgAvatar} from "../images/GenerateOnboardingSvg/GenerateSvg";
|
||||
import Logo from "../images/logo.png";
|
||||
import {registrationStore} from "../store/registrationStore";
|
||||
import {registrationStore} from "../store/store";
|
||||
import { passphrase } from "@liskhq/lisk-client";
|
||||
|
||||
function Onboarding3() {
|
||||
const [passPhrase, setPassPhrase] = useState(registrationStore.passPhraseStore.replace(/\s+/g, ' ').split(' ').map((item, index) => ({str:item, id:index })))
|
||||
const [passPhrase, setPassPhrase] = useState(convertPhraseToArray(registrationStore.passPhrase))
|
||||
function generatePassPhrase() {
|
||||
let phrase = passphrase.Mnemonic.generateMnemonic()
|
||||
registrationStore.savePassPhrase(phrase)
|
||||
let newPassPhrase = registrationStore.passPhraseStore.split(' ').map((item, index) => ({str:item, id:index }))
|
||||
setPassPhrase(newPassPhrase)
|
||||
setPassPhrase(convertPhraseToArray(registrationStore.passPhrase))
|
||||
}
|
||||
|
||||
function savePassPhraseInStore (copiedPhrase) {
|
||||
let phrasePaste = copiedPhrase.trim().replace(/\s+/g, ' ').split(' ')
|
||||
let phrasePaste = convertPhraseToArray(copiedPhrase.trim())
|
||||
if(phrasePaste.length===12) {
|
||||
registrationStore.savePassPhrase(copiedPhrase)
|
||||
setPassPhrase(phrasePaste.map((item, index) => ({str:item, id:index })))
|
||||
registrationStore.savePassPhrase(copiedPhrase.trim())
|
||||
setPassPhrase(phrasePaste)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
@@ -28,6 +27,10 @@ function Onboarding3() {
|
||||
navigator.clipboard.readText().then(res=>savePassPhraseInStore(res))
|
||||
}
|
||||
|
||||
function convertPhraseToArray(phrase) {
|
||||
return phrase.split(' ').map((item, index) => ({str:item, id:index }))
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<main className="bg-white">
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
import React, {useEffect, useState} 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/registrationStore";
|
||||
import { registrationStore } from "../store/store";
|
||||
|
||||
const Onboarding4 = observer(()=>{
|
||||
|
||||
const [checkBoxesSelected, setCheckBoxesSelected] = useState(false)
|
||||
|
||||
function validateCheckBox () {
|
||||
let checkBoxes=[...document.getElementsByClassName("form-checkbox")]
|
||||
if(checkBoxes.find(item=>item.checked===false)) {
|
||||
return
|
||||
} else {
|
||||
setCheckBoxesSelected(true)
|
||||
const [checkBoxesSelected, setCheckBoxesSelected] = useState([])
|
||||
|
||||
function createAccount () {
|
||||
if(checkBoxesSelected.length===2) {
|
||||
registrationStore.pushAccountData()
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
if(checkBoxesSelected===true) {
|
||||
document.getElementById("link-dashboard").click()
|
||||
function saveCheckBoxesValues(e) {
|
||||
const { id, checked } = e.target
|
||||
setCheckBoxesSelected([...checkBoxesSelected, id])
|
||||
if (!checked) {
|
||||
setCheckBoxesSelected(checkBoxesSelected.filter(item=>item!==id))
|
||||
}
|
||||
},[checkBoxesSelected])
|
||||
}
|
||||
|
||||
const firstNameAccount = registrationStore.accountData.length && registrationStore.accountData.find(item=>item.key==="first_name").value
|
||||
|
||||
return (
|
||||
<main className="bg-white">
|
||||
@@ -80,20 +80,20 @@ const Onboarding4 = observer(()=>{
|
||||
<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">{registrationStore.accountData.first_name ? `Nice to meet you, ${registrationStore.accountData.first_name} 🙌` : 'Please, go back step 2'}</h1>
|
||||
<button onClick={()=>validateCheckBox()} className="btn px-6 bg-indigo-500 hover:bg-indigo-600 text-white">
|
||||
<Link id="link-dashboard" to={checkBoxesSelected && "/dashboard"}>Go To Profile -></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 -></Link>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<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">
|
||||
I <Link className="text-indigo-500 hover:text-indigo-600 underline" to="/">store my pharse</Link> very carefuly
|
||||
</div>
|
||||
|
||||
@@ -1,34 +1,89 @@
|
||||
import React, { useState } from 'react';
|
||||
import { userDataStore } from '../../store/userDataStore';
|
||||
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 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 Profile = observer (() => {
|
||||
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 defaultValues = {
|
||||
label: '',
|
||||
value: '',
|
||||
seed: Math.floor(Math.random() * 90000000000000000000)
|
||||
};
|
||||
|
||||
const initialPropertyValues = ['First name', 'Second name', 'Birthdate', 'Gender', 'National doctype', 'National doc id', 'National doc issue date', 'National doc expiry date'];
|
||||
const [propertyValues, setPropertyValues] = useState([]);
|
||||
const [updatedValues, setUpdatedValues] = useState([defaultValues]);
|
||||
const [addedValues, setAddedValues] = useState(defaultValues);
|
||||
|
||||
const openHint = () => {
|
||||
if (!addedValues.label) {
|
||||
setPropertyValues(initialPropertyValues);
|
||||
}
|
||||
}
|
||||
|
||||
const changeAddedValues = (value, field) => {
|
||||
setAddedValues((prevState) => (
|
||||
field !== 'seed' ? {
|
||||
...prevState,
|
||||
[field]: value
|
||||
} : {
|
||||
...prevState,
|
||||
[field]: +value,
|
||||
}))
|
||||
};
|
||||
|
||||
const changeUpdatedValues = (value, field, key) => {
|
||||
setUpdatedValues((prevState) =>
|
||||
prevState.map((elem) => (
|
||||
(elem.key === key && field !== 'seed') ? {
|
||||
...elem,
|
||||
[field]: value,
|
||||
} :
|
||||
(elem.key === key) ? {
|
||||
...elem,
|
||||
[field]: +value,
|
||||
} : elem
|
||||
))
|
||||
)
|
||||
};
|
||||
|
||||
const closeHint = (element) => {
|
||||
changeAddedValues(element, 'label');
|
||||
setPropertyValues([]);
|
||||
}
|
||||
|
||||
const handleSelectedItems = (selectedItems) => {
|
||||
setSelectedItems([...selectedItems]);
|
||||
setUpdatedValues(userDataStore.decryptedData.filter(({ key }) => selectedItems.includes(key))
|
||||
.map(elem => (
|
||||
(!elem.seed) ? {
|
||||
...elem,
|
||||
seed: Math.floor(Math.random() * 90000000000000000000)
|
||||
}: 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);
|
||||
}
|
||||
@@ -39,155 +94,90 @@ function Profile () {
|
||||
setButtonPanelOpen(false);
|
||||
}
|
||||
|
||||
const sendAddedData = () => {
|
||||
if (!userDataStore.decryptedData.some((element) => element.label === addedValues.label) && (addedValues.seed.toString().length === 20)) {
|
||||
setAddPanelOpen(false);
|
||||
setButtonPanelOpen(true);
|
||||
setAddedValues(defaultValues);
|
||||
addDataParameters();
|
||||
}
|
||||
}
|
||||
|
||||
const sendUpdatedData = () => {
|
||||
setUpdatePanelOpen(false);
|
||||
changeDataParameters();
|
||||
setChangePanelOpen(true);
|
||||
}
|
||||
|
||||
const deleteDataParameters = () => {
|
||||
const changeData = userDataStore.decryptedData.filter(item=>!selectedItems.includes(item.key))
|
||||
registrationStore.pushAccountData(changeData);
|
||||
}
|
||||
|
||||
const changeInitialArray = () => {
|
||||
let newArr = [];
|
||||
userDataStore.decryptedData.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(userDataStore.decryptedData.concat(addedValues));
|
||||
}
|
||||
|
||||
const cancelAddPanel = () => {
|
||||
setAddedValues(defaultValues);
|
||||
setAddPanelOpen(false);
|
||||
setButtonPanelOpen(true);
|
||||
}
|
||||
|
||||
const cancelUpdatePanel = () => {
|
||||
setUpdatePanelOpen(false);
|
||||
setChangePanelOpen(true);
|
||||
}
|
||||
|
||||
const openRemovePanel = () => {
|
||||
setRemovePanelOpen(true);
|
||||
setChangePanelOpen(false);
|
||||
}
|
||||
|
||||
const applyRemovePanel = () => {
|
||||
setRemovePanelOpen(false);
|
||||
setButtonPanelOpen(true);
|
||||
const openUpdatePanel = () => {
|
||||
setUpdatePanelOpen(true);
|
||||
setChangePanelOpen(false);
|
||||
}
|
||||
|
||||
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 applyDataDeletion = () => {
|
||||
setRemovePanelOpen(false);
|
||||
setButtonPanelOpen(true);
|
||||
deleteDataParameters()
|
||||
}
|
||||
|
||||
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 +212,7 @@ function Profile () {
|
||||
</ul>
|
||||
</div>
|
||||
{/* Table */}
|
||||
<ProfileTable selectedItems={handleSelectedItems} userData={userData}/>
|
||||
<ProfileTable selectedItems={handleSelectedItems} userData={userDataStore.decryptedData}/>
|
||||
</div>
|
||||
{/* Left sidebar */}
|
||||
<div>
|
||||
@@ -246,22 +236,56 @@ function Profile () {
|
||||
<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 />
|
||||
<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}
|
||||
/>
|
||||
<div className={`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 key={index} onClick={() => closeHint(element)}>{element}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</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 />
|
||||
<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>
|
||||
<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 />
|
||||
<input
|
||||
autoComplete='off'
|
||||
id="seed"
|
||||
className="form-input w-full"
|
||||
type="number"
|
||||
required
|
||||
onClick={() => setPropertyValues([])}
|
||||
onChange={(e) => changeAddedValues(e.target.value, 'seed')}
|
||||
value={addedValues.seed}
|
||||
/>
|
||||
</div>
|
||||
</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>
|
||||
@@ -278,7 +302,79 @@ function Profile () {
|
||||
</button>
|
||||
<button
|
||||
className="btn-sm bg-indigo-500 hover:bg-indigo-600 text-white"
|
||||
onClick={cancelAddPanel}
|
||||
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="number"
|
||||
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="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 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={cancelUpdatePanel}
|
||||
>
|
||||
Cansel
|
||||
</button>
|
||||
<button
|
||||
className="btn-sm bg-indigo-500 hover:bg-indigo-600 text-white"
|
||||
onClick={sendUpdatedData}
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
@@ -288,8 +384,8 @@ function Profile () {
|
||||
<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>
|
||||
{userDataStore.decryptedData.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-7 items-center">
|
||||
@@ -306,7 +402,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" />
|
||||
@@ -369,7 +465,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 +489,6 @@ function Profile () {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default Profile;
|
||||
export default Profile
|
||||
|
||||
@@ -1,70 +1,18 @@
|
||||
import React, { useState } from 'react';
|
||||
import {observer} from "mobx-react-lite";
|
||||
|
||||
import {transactionsStore} from "../../store/transactionsStore";
|
||||
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 {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";
|
||||
|
||||
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 */}
|
||||
@@ -110,7 +58,7 @@ function Validate () {
|
||||
<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 => {
|
||||
{transactionsStore.transactionsData.map(item => {
|
||||
return <ValidateRoadMap season={item} key={item.id}/>
|
||||
})}
|
||||
</div>
|
||||
@@ -120,6 +68,6 @@ function Validate () {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default Validate;
|
||||
|
||||
@@ -1,115 +1,14 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, {useState} from 'react';
|
||||
|
||||
import ValidateRoadMap from "../../partials/validationlog/ValidateRoadMap";
|
||||
import {transactionsStore} from "../../store/transactionsStore";
|
||||
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";
|
||||
|
||||
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 */}
|
||||
@@ -129,61 +28,9 @@ function ValidationLog () {
|
||||
<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} />
|
||||
{transactionsStore.transactionsData.map(item=>{
|
||||
return <ValidateRoadMap season={item} key={item.id}/>
|
||||
})}
|
||||
{/* Post */}
|
||||
<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">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 +38,6 @@ function ValidationLog () {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default ValidationLog;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import ProfileTableItem from './ProfileTableItem';
|
||||
import ProfileIcon from '../../images/profile-icon.svg';
|
||||
|
||||
function ProfileTable({
|
||||
selectedItems,
|
||||
@@ -8,6 +9,13 @@ function ProfileTable({
|
||||
|
||||
const [isCheck, setIsCheck] = useState([]);
|
||||
|
||||
const defaultData = {
|
||||
image: ProfileIcon,
|
||||
status: 'Stored',
|
||||
transactions: ['0x7234ABC342342352345', '0x5745DEF342342352345'],
|
||||
avatars: null
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
selectedItems(isCheck);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -21,85 +29,123 @@ function ProfileTable({
|
||||
}
|
||||
};
|
||||
|
||||
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)),
|
||||
nationalityData = userData.filter(elem => data.nationality.includes(elem.label)),
|
||||
sosialData = userData.filter(elem => data.social.includes(elem.label)),
|
||||
otherData = userData.filter((elem) =>
|
||||
!data.general.includes(elem.label) && !data.nationality.includes(elem.label) && !data.social.includes(elem.label));
|
||||
|
||||
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 => {
|
||||
<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.id}
|
||||
id={data.id}
|
||||
image={data.image}
|
||||
value={data.value}
|
||||
property={data.property}
|
||||
status={data.status}
|
||||
transactions={data.transactions}
|
||||
avatars={data.avatars}
|
||||
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.id)}
|
||||
isChecked={isCheck.includes(data.key)}
|
||||
/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</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 => {
|
||||
<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.id}
|
||||
id={data.id}
|
||||
image={data.image}
|
||||
value={data.value}
|
||||
property={data.property}
|
||||
status={data.status}
|
||||
transactions={data.transactions}
|
||||
avatars={data.avatars}
|
||||
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.id)}
|
||||
isChecked={isCheck.includes(data.key)}
|
||||
/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</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 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>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -9,15 +9,15 @@ function ValidateRoadMap({ season }) {
|
||||
<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">
|
||||
<div className="grow pb-6">
|
||||
<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>
|
||||
|
||||
@@ -5,21 +5,21 @@ function ValidationSeasonItem({ length, item, index }) {
|
||||
<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="absolute left-0 rounded-full bg-indigo-500" 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"/>}
|
||||
<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} by`} <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>
|
||||
<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>
|
||||
<div className="text-base font-semibold underline mb-[-10px]">{item.value}</div>
|
||||
<span className="font-normal text-slate-600 text-[10px]">Validated data</span>
|
||||
</div>
|
||||
<a className="cursor-pointer pl-9 font-normal text-sm text-indigo-500 hover:text-indigo-600">Explore -></a>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import {registrationStore} from '../store/store';
|
||||
|
||||
function prepareUrl(url) {
|
||||
if (url.startsWith('http')) return url;
|
||||
return `/api/${url}`;
|
||||
return `http://3.125.47.101/api/${url}`;
|
||||
}
|
||||
|
||||
function handleRequest(method, url, attempts, token, body) {
|
||||
function handleRequest(method, url, headers, attempts, token, body) {
|
||||
return new Promise((resolve, reject) => {
|
||||
(function internalRequest() {
|
||||
return request(method, url, token, body)
|
||||
return request(method, url, headers, token, body)
|
||||
.then(resolve)
|
||||
.catch(err => --attempts > 0 ? internalRequest() : reject(err))
|
||||
})()
|
||||
@@ -17,17 +19,21 @@ function handleRequest(method, url, attempts, token, body) {
|
||||
|
||||
/**
|
||||
* 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, token, body) {
|
||||
function request(method, url, headers = {}, token, body) {
|
||||
let controller = new AbortController;
|
||||
let requestOptions = {};
|
||||
if (method === 'GET' || method === 'DELETE'){
|
||||
requestOptions = {
|
||||
method: method,
|
||||
headers: {
|
||||
Authorization: `Token ${token}`,
|
||||
Authorization: `IDNTTY ${token}`,
|
||||
...headers
|
||||
},
|
||||
signal: controller.signal,
|
||||
}
|
||||
@@ -36,9 +42,10 @@ function request(method, url, token, body) {
|
||||
requestOptions = {
|
||||
method: method,
|
||||
headers: {
|
||||
Authorization: `Token ${token}`,
|
||||
Authorization: `IDNTTY ${token}`,
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
...headers
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
signal: controller.signal,
|
||||
@@ -48,39 +55,39 @@ function request(method, url, token, body) {
|
||||
requestOptions.headers.Authorization = null;
|
||||
}
|
||||
setTimeout(() => controller.abort(), 3000);
|
||||
return fetch(url, requestOptions);
|
||||
return fetch(prepareUrl(url), requestOptions);
|
||||
};
|
||||
|
||||
function get(url, attempts = 1) {
|
||||
return handleRequest('GET', url, attempts, null);
|
||||
function get(url, headers, attempts = 1) {
|
||||
return handleRequest('GET', url, headers, attempts, null);
|
||||
}
|
||||
|
||||
function getAuth(url, attempts = 1) {
|
||||
return handleRequest('GET', url, attempts, registrationStore.tokenKey);
|
||||
function getAuth(url, headers, attempts = 1) {
|
||||
return handleRequest('GET', url, headers, attempts, registrationStore.tokenKey);
|
||||
}
|
||||
|
||||
function del(url, attempts = 1) {
|
||||
return handleRequest('DELETE', url, attempts, null);
|
||||
function del(url, headers, attempts = 1) {
|
||||
return handleRequest('DELETE', url, headers, attempts, null);
|
||||
}
|
||||
|
||||
function delAuth(url, attempts = 1) {
|
||||
return handleRequest('DELETE', url, attempts, registrationStore.tokenKey);
|
||||
function delAuth(url, headers, attempts = 1) {
|
||||
return handleRequest('DELETE', url, headers, attempts, registrationStore.tokenKey);
|
||||
}
|
||||
|
||||
function post(url, body, attempts = 1) {
|
||||
return handleRequest('POST', url, attempts, null, body);
|
||||
function post(url, headers, body, attempts = 1) {
|
||||
return handleRequest('POST', url, headers, attempts, null, body);
|
||||
}
|
||||
|
||||
function postAuth(url, body, attempts = 1) {
|
||||
return handleRequest('POST', url, attempts, registrationStore.tokenKey, body);
|
||||
function postAuth(url, headers, body, attempts = 1) {
|
||||
return handleRequest('POST', url, headers, attempts, registrationStore.tokenKey, body);
|
||||
}
|
||||
|
||||
function put(url, body, attempts = 1) {
|
||||
return handleRequest('PUT', url, attempts, null, body);
|
||||
function put(url, headers, body, attempts = 1) {
|
||||
return handleRequest('PUT', url, headers, attempts, null, body);
|
||||
}
|
||||
|
||||
function putAuth(url, body, attempts = 1) {
|
||||
return handleRequest('PUT', url, attempts, registrationStore.tokenKey, body);
|
||||
function putAuth(url, headers, body, attempts = 1) {
|
||||
return handleRequest('PUT', url, headers, attempts, registrationStore.tokenKey, body);
|
||||
}
|
||||
|
||||
export const fetchWrapper = {
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import { reaction, makeAutoObservable } from "mobx";
|
||||
import {cryptography} from "@liskhq/lisk-client";
|
||||
|
||||
class RegistrationStore {
|
||||
_accountData = {}
|
||||
|
||||
_passPhraseStore=''
|
||||
|
||||
_pubKey = ''
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
reaction(()=>this.passPhraseStore, ()=>this.savePubKey())
|
||||
};
|
||||
|
||||
savePassPhrase(phrase) {
|
||||
this._passPhraseStore = phrase
|
||||
}
|
||||
|
||||
saveDataRegistration(data) {
|
||||
this._accountData = data;
|
||||
};
|
||||
savePubKey() {
|
||||
this._pubKey = cryptography.bufferToHex(cryptography.getAddressAndPublicKeyFromPassphrase(this.passPhraseStore).publicKey)
|
||||
}
|
||||
|
||||
get passPhraseStore() {
|
||||
return this._passPhraseStore
|
||||
}
|
||||
|
||||
get accountData() {
|
||||
return this._accountData
|
||||
};
|
||||
|
||||
get pubKey() {
|
||||
return this._pubKey
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export const registrationStore = new RegistrationStore();
|
||||
136
src/store/store.js
Normal file
136
src/store/store.js
Normal file
@@ -0,0 +1,136 @@
|
||||
import { reaction, makeAutoObservable } from "mobx";
|
||||
import {cryptography} from "@liskhq/lisk-client";
|
||||
import {getNodeInfo} from '../api/node';
|
||||
import {fetchWrapper} from '../shared/fetchWrapper';
|
||||
|
||||
class Store {
|
||||
_accountData = []
|
||||
|
||||
_passPhrase='rocket north inform swift improve fringe sweet crew client canyon bean autumn'
|
||||
|
||||
_nodeInfo = {}
|
||||
|
||||
_userData = {}
|
||||
|
||||
_transactionsInfo = {}
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
|
||||
this.fetchNodeInfo()
|
||||
|
||||
reaction(() => this.tokenKey, () => this.fetchNewAccountData())
|
||||
reaction(() => this.tokenKey, () => this.fetchTransactionsInfo())
|
||||
};
|
||||
|
||||
fetchNewAccountData() {
|
||||
fetchWrapper.getAuth('http://3.125.47.101/api/data/private', {
|
||||
networkIdentifier: this.nodeInfo.networkIdentifier,
|
||||
lastBlockID: this.nodeInfo.lastBlockID
|
||||
}).then((res) => this.userDataFetchChange(res))
|
||||
}
|
||||
|
||||
pushAccountData(data=this.accountData) {
|
||||
fetchWrapper.postAuth('http://3.125.47.101/api/data/private', {
|
||||
networkIdentifier: this.nodeInfo.networkIdentifier,
|
||||
lastBlockID: this.nodeInfo.lastBlockID
|
||||
}, [...this.encryptAccountData(data)])
|
||||
.then(()=>this.fetchNewAccountData())
|
||||
}
|
||||
|
||||
fetchTransactionsInfo() {
|
||||
fetchWrapper.getAuth(`http://3.125.47.101/api/account/transactions/${this.accountMadeTransaction}?moduleID=1001&assetID=11`, {
|
||||
networkIdentifier: this.nodeInfo.networkIdentifier,
|
||||
lastBlockID: this.nodeInfo.lastBlockID
|
||||
})
|
||||
.then((res)=>this.saveInfoTransactions(res))
|
||||
}
|
||||
|
||||
get accountMadeTransaction() {
|
||||
return "b444b7ff3118cf2a30cbd54cfcdb8fd5d805017a"
|
||||
}
|
||||
|
||||
userDataFetchChange(res) {
|
||||
this._userData = res;
|
||||
}
|
||||
|
||||
get userData() {
|
||||
return this._userData
|
||||
}
|
||||
|
||||
get transactionsInfo() {
|
||||
return this._transactionsInfo
|
||||
}
|
||||
|
||||
savePassPhrase(phrase) {
|
||||
this._passPhrase = phrase
|
||||
}
|
||||
|
||||
saveDataRegistration(data) {
|
||||
this._accountData = data;
|
||||
};
|
||||
|
||||
saveInfoTransactions(transaction) {
|
||||
this._transactionsInfo = transaction
|
||||
}
|
||||
|
||||
fetchNodeInfo() {
|
||||
getNodeInfo()
|
||||
.then((info) => this.fetchNodeInfoSuccess(info))
|
||||
.catch((err) => this.fetchNodeInfoFailed(err))
|
||||
}
|
||||
|
||||
fetchNodeInfoSuccess(info) {
|
||||
this._nodeInfo = info.data;
|
||||
}
|
||||
|
||||
fetchNodeInfoFailed(err) {
|
||||
console.log(err)
|
||||
}
|
||||
|
||||
get passPhrase() {
|
||||
return 'rocket north inform swift improve fringe sweet crew client canyon bean autumn'
|
||||
}
|
||||
|
||||
get accountData() {
|
||||
return this._accountData
|
||||
};
|
||||
|
||||
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,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get nodeInfo() {
|
||||
return this._nodeInfo;
|
||||
}
|
||||
|
||||
get addressAndPubKey() {
|
||||
return cryptography.getAddressAndPublicKeyFromPassphrase(this.passPhrase);
|
||||
}
|
||||
|
||||
get pubKey() {
|
||||
return this.addressAndPubKey.publicKey.toString('hex');
|
||||
}
|
||||
|
||||
get address() {
|
||||
return cryptography.bufferToHex(this.addressAndPubKey.address)
|
||||
}
|
||||
|
||||
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();
|
||||
51
src/store/transactionsStore.js
Normal file
51
src/store/transactionsStore.js
Normal file
@@ -0,0 +1,51 @@
|
||||
import {makeAutoObservable, reaction} from "mobx";
|
||||
import {registrationStore} from "./store";
|
||||
import User05 from "../../src/images/user-28-05.jpg";
|
||||
import User08 from "../../src/images/user-28-08.jpg";
|
||||
import User09 from "../../src/images/user-28-09.jpg";
|
||||
import User06 from "../../src/images/user-28-06.jpg";
|
||||
|
||||
const labelMap = {
|
||||
firstname: 'First name',
|
||||
secondname: 'Second name',
|
||||
gender: "Gender",
|
||||
birthdate: "Birthdate"
|
||||
};
|
||||
|
||||
const usersImages = [User08,User06,User05,User09];
|
||||
|
||||
class TransactionsStore {
|
||||
_transactionsData = [];
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this)
|
||||
|
||||
reaction(() => ({data: registrationStore.transactionsInfo}), ({data}) => {
|
||||
this._transactionsData = data.data;
|
||||
})
|
||||
}
|
||||
|
||||
get transactionsData() {
|
||||
return this._transactionsData.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: registrationStore.accountMadeTransaction,
|
||||
value: asset.value,
|
||||
label: labelMap[asset.label],
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const transactionsStore = new TransactionsStore()
|
||||
53
src/store/userDataStore.js
Normal file
53
src/store/userDataStore.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import { cryptography } from "@liskhq/lisk-client";
|
||||
import { makeAutoObservable, reaction } from "mobx";
|
||||
import { registrationStore } from './store';
|
||||
|
||||
const labelMap = {
|
||||
first_name: 'First name',
|
||||
second_name: 'Second name',
|
||||
gender: "Gender",
|
||||
birthdate: "Birthdate",
|
||||
place_of_birth: "Place of birth",
|
||||
nationality: "Nationality",
|
||||
national_id: "National ID",
|
||||
national_doctype: "National doctype",
|
||||
national_doc_id: "National doc ID",
|
||||
national_doc_issue_date: "National doc issue date",
|
||||
national_doc_expiry_date: "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"
|
||||
};
|
||||
|
||||
class UserDataStore{
|
||||
_data = [];
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
|
||||
reaction(() => ({data: registrationStore.userData}), ({data}) => {
|
||||
this._data = data.data;
|
||||
})
|
||||
}
|
||||
get decryptedData(){
|
||||
return this._data.map((elem) => ({
|
||||
...elem,
|
||||
key: elem.label,
|
||||
label: labelMap[elem.label],
|
||||
value: cryptography.decryptMessageWithPassphrase(elem.value, elem.value_nonce, registrationStore.passPhrase, registrationStore.pubKey).split(':')[1]
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
export const userDataStore = new UserDataStore();
|
||||
Reference in New Issue
Block a user