@@ -2,9 +2,64 @@ import React, { useState } from 'react';
|
|||||||
|
|
||||||
import Sidebar from '../../partials/Sidebar';
|
import Sidebar from '../../partials/Sidebar';
|
||||||
import Header from '../../partials/Header';
|
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 () {
|
function Validate () {
|
||||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||||
|
const [validatePanelOpen, setValidatePanelOpen] = useState(true);
|
||||||
|
|
||||||
|
const validateItems = [
|
||||||
|
{
|
||||||
|
id: '40',
|
||||||
|
name: 'Today',
|
||||||
|
data: '7234ABC342342352345',
|
||||||
|
usersImges: [
|
||||||
|
{
|
||||||
|
img: User06,
|
||||||
|
imgId: "343"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: User08,
|
||||||
|
imgId: "345"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: User09,
|
||||||
|
imgId: "321"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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 (
|
return (
|
||||||
<div className="flex h-screen overflow-hidden">
|
<div className="flex h-screen overflow-hidden">
|
||||||
@@ -16,12 +71,47 @@ function Validate () {
|
|||||||
<Header sidebarOpen={sidebarOpen} setSidebarOpen={setSidebarOpen} />
|
<Header sidebarOpen={sidebarOpen} setSidebarOpen={setSidebarOpen} />
|
||||||
<main>
|
<main>
|
||||||
<div className="px-4 sm:px-6 lg:px-8 py-8 w-full max-w-9xl mx-auto">
|
<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 */}
|
{/* Page header */}
|
||||||
<div className="mb-8">
|
<div className="pb-2.5">
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<h1 className="text-2xl md:text-3xl text-slate-800 font-bold">Validate ✨</h1>
|
<h1 className="text-2xl md:text-3xl text-slate-800 font-bold">0x28394710234192304719234</h1>
|
||||||
|
</div>
|
||||||
|
<Link className="font-normal text-sm text-indigo-500 hover:text-indigo-600" to="/digitalId/validate">Explore -></Link>
|
||||||
|
<div className="mb-5 mt-5">
|
||||||
|
<ul className="flex flex-wrap -m-1">
|
||||||
|
<li className="m-1">
|
||||||
|
<button className="inline-flex items-center justify-center text-sm font-medium leading-5 rounded-full px-3 py-1 border border-transparent shadow-sm bg-indigo-500 text-white duration-150 ease-in-out">
|
||||||
|
View All
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li className="m-1">
|
||||||
|
<button className="inline-flex items-center justify-center text-sm font-medium leading-5 rounded-full px-3 py-1 border border-slate-200 hover:border-slate-300 shadow-sm bg-white text-slate-500 duration-150 ease-in-out">
|
||||||
|
Correct
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li className="m-1">
|
||||||
|
<button className="inline-flex items-center justify-center text-sm font-medium leading-5 rounded-full px-3 py-1 border border-slate-200 hover:border-slate-300 shadow-sm bg-white text-slate-500 duration-150 ease-in-out">
|
||||||
|
Incorect
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li className="m-1">
|
||||||
|
<button className="inline-flex items-center justify-center text-sm font-medium leading-5 rounded-full px-3 py-1 border border-slate-200 hover:border-slate-300 shadow-sm bg-white text-slate-500 duration-150 ease-in-out">
|
||||||
|
Missed
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</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>
|
||||||
|
{validateItems.map(item => {
|
||||||
|
return <ValidateRoadMap season={item} key={item.id}/>
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<ValidatePanel validatePanelOpen={validatePanelOpen} setValidatePanelOpen={setValidatePanelOpen}/>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,11 +1,107 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
import ValidateRoadMap from "../../partials/validationlog/ValidateRoadMap";
|
||||||
import Sidebar from '../../partials/Sidebar';
|
import Sidebar from '../../partials/Sidebar';
|
||||||
import Header from '../../partials/Header';
|
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 () {
|
function ValidationLog () {
|
||||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||||
|
|
||||||
|
const logItems = [
|
||||||
|
{
|
||||||
|
id: '20',
|
||||||
|
name: 'Today',
|
||||||
|
data: '7234ABC342342352345',
|
||||||
|
usersImges: [
|
||||||
|
{
|
||||||
|
img: User06,
|
||||||
|
imgId: "249"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: User08,
|
||||||
|
imgId: "212"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: User09,
|
||||||
|
imgId: "217"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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: [
|
||||||
|
{
|
||||||
|
img: User06,
|
||||||
|
imgId: "145"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: User08,
|
||||||
|
imgId: "182"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
img: User09,
|
||||||
|
imgId: "154"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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 (
|
return (
|
||||||
<div className="flex h-screen overflow-hidden">
|
<div className="flex h-screen overflow-hidden">
|
||||||
{/* Sidebar */}
|
{/* Sidebar */}
|
||||||
@@ -17,9 +113,70 @@ function ValidationLog () {
|
|||||||
<main>
|
<main>
|
||||||
<div className="px-4 sm:px-6 lg:px-8 py-8 w-full max-w-9xl mx-auto">
|
<div className="px-4 sm:px-6 lg:px-8 py-8 w-full max-w-9xl mx-auto">
|
||||||
{/* Page header */}
|
{/* Page header */}
|
||||||
<div className="mb-8">
|
<div className="pb-8 border-b border-zinc-200">
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<h1 className="text-2xl md:text-3xl text-slate-800 font-bold">Validation log ✨</h1>
|
<h1 className="text-2xl md:text-3xl text-slate-800 font-bold">Digiatl ID transaction log ✨</h1>
|
||||||
|
</div>
|
||||||
|
{/*Psosts*/}
|
||||||
|
<div className="max-w-3xl m-auto mt-8">
|
||||||
|
<div className="xl:-translate-x-16 max-w-fit">
|
||||||
|
{/* PostsID */}
|
||||||
|
{logItems.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>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
62
src/partials/validate/ValidateItem.jsx
Normal file
62
src/partials/validate/ValidateItem.jsx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function ValidateTableItem(props) {
|
||||||
|
|
||||||
|
const statusColor = (status) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'Correct':
|
||||||
|
return 'bg-emerald-100 text-emerald-600';
|
||||||
|
case 'Incorrect':
|
||||||
|
return 'bg-rose-100 text-rose-500';
|
||||||
|
default:
|
||||||
|
return 'bg-slate-100 text-slate-500';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function openValidatePanel (event) {
|
||||||
|
event.stopPropagation()
|
||||||
|
props.setValidatePanelOpen(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
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">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<label className="inline-flex">
|
||||||
|
<span className="sr-only">Select</span>
|
||||||
|
{props.check && <input id={props.id} className="form-checkbox" type="checkbox" onChange={props.handleClick} checked={props.isChecked} onClick={(e) => e.stopPropagation()} />}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap md:w-1/2">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div>{props.filed}</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
||||||
|
<div className="text-left font-medium text-slate-800">{props.data}</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap w-px">
|
||||||
|
<div className={`text-left`}>{props.seed}</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-2 first:pl-5 py-3 whitespace-nowrap">
|
||||||
|
<div className="text-left">
|
||||||
|
<div className={`text-xs inline-flex font-medium rounded-full text-center px-2.5 py-1 ${statusColor(props.status)}`}>{props.status}</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="px-2 first:pl-5 last:pr-5 pt-3 pb-2 whitespace-nowrap w-px">
|
||||||
|
{/* Menu button */}
|
||||||
|
<button className="text-slate-400 hover:text-slate-500 rounded-full">
|
||||||
|
<span className="sr-only">Menu</span>
|
||||||
|
<svg className="w-8 h-8 fill-current" viewBox="0 0 32 32">
|
||||||
|
<circle cx="16" cy="16" r="2" />
|
||||||
|
<circle cx="10" cy="16" r="2" />
|
||||||
|
<circle cx="22" cy="16" r="2" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ValidateTableItem;
|
||||||
136
src/partials/validate/ValidatePanel.jsx
Normal file
136
src/partials/validate/ValidatePanel.jsx
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
import React, { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
import Image from '../../images/transactions-image-04.svg';
|
||||||
|
|
||||||
|
function TransactionPanel({
|
||||||
|
validatePanelOpen,
|
||||||
|
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)]">
|
||||||
|
<button
|
||||||
|
ref={closeBtn}
|
||||||
|
onClick={() => setValidatePanelOpen(false)}
|
||||||
|
className="absolute top-0 right-0 mt-6 mr-6 group p-2"
|
||||||
|
>
|
||||||
|
<svg className="w-4 h-4 fill-slate-400 group-hover:fill-slate-600 pointer-events-none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="m7.95 6.536 4.242-4.243a1 1 0 1 1 1.415 1.414L9.364 7.95l4.243 4.242a1 1 0 1 1-1.415 1.415L7.95 9.364l-4.243 4.243a1 1 0 0 1-1.414-1.415L6.536 7.95 2.293 3.707a1 1 0 0 1 1.414-1.414L7.95 6.536Z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<div className="py-8 px-4 lg:px-8">
|
||||||
|
<div className="max-w-sm mx-auto lg:max-w-none">
|
||||||
|
<div className="text-slate-800 font-semibold text-center mb-1">Bank Transfer</div>
|
||||||
|
<div className="text-sm text-center italic">22/01/2022, 8:56 PM</div>
|
||||||
|
{/* Details */}
|
||||||
|
<div className="drop-shadow-lg mt-12">
|
||||||
|
{/* Top */}
|
||||||
|
<div className="bg-white rounded-t-xl px-5 pb-2.5 text-center">
|
||||||
|
<div className="mb-3 text-center">
|
||||||
|
<img className="inline-flex w-12 h-12 rounded-full -mt-6" src={Image} width="48" height="48" alt="Transaction 04" />
|
||||||
|
</div>
|
||||||
|
<div className="mt-5 text-2xl font-semibold text-emerald-500 mb-1">0.012 IDN</div>
|
||||||
|
<div className="text-sm font-medium text-slate-800 mb-3">Total amount fee</div>
|
||||||
|
</div>
|
||||||
|
{/* Divider */}
|
||||||
|
<div className="flex justify-between items-center" aria-hidden="true">
|
||||||
|
<svg className="w-5 h-5 fill-white" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 20c5.523 0 10-4.477 10-10S5.523 0 0 0h20v20H0Z" />
|
||||||
|
</svg>
|
||||||
|
<div className="grow w-full h-5 bg-white flex flex-col justify-center">
|
||||||
|
<div className="h-px w-full border-t border-dashed border-slate-200" />
|
||||||
|
</div>
|
||||||
|
<svg className="w-5 h-5 fill-white rotate-180" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0 20c5.523 0 10-4.477 10-10S5.523 0 0 0h20v20H0Z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
{/* Bottom */}
|
||||||
|
<div className="bg-white rounded-b-xl p-5 pt-8 pb-10 text-sm space-y-3">
|
||||||
|
<div className="flex justify-between space-x-1">
|
||||||
|
<span className="italic">Validator:</span>
|
||||||
|
<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">Recipient:</span>
|
||||||
|
<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="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">
|
||||||
|
<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>
|
||||||
|
<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>
|
||||||
|
<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={""} />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{/* Download / Report */}
|
||||||
|
<div className="flex items-center space-x-3 mt-6">
|
||||||
|
<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>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="w-1/2">
|
||||||
|
<button className="btn w-full border-slate-200 hover:border-slate-300 text-rose-500">
|
||||||
|
<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>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TransactionPanel;
|
||||||
135
src/partials/validate/ValidateTable.jsx
Normal file
135
src/partials/validate/ValidateTable.jsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import ValidateTableItem from "./ValidateItem";
|
||||||
|
|
||||||
|
function ValidateTable({
|
||||||
|
setValidatePanelOpen
|
||||||
|
}) {
|
||||||
|
|
||||||
|
const validateData = [
|
||||||
|
{
|
||||||
|
id: '10',
|
||||||
|
check: true,
|
||||||
|
filed: 'Second name',
|
||||||
|
data: 'Pavel',
|
||||||
|
status: 'Correct',
|
||||||
|
seed: '1234 ... 1234',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '11',
|
||||||
|
check: true,
|
||||||
|
filed: 'First name',
|
||||||
|
data: 'Thownetc',
|
||||||
|
status: 'Correct',
|
||||||
|
seed: '4567 ... 0987',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '12',
|
||||||
|
check: false,
|
||||||
|
filed: 'Gender',
|
||||||
|
data: 'Female',
|
||||||
|
status: 'Incorrect',
|
||||||
|
seed: '4567 ... 0987',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '13',
|
||||||
|
check: false,
|
||||||
|
filed: 'Document',
|
||||||
|
data: 'Passport',
|
||||||
|
status: 'Missed',
|
||||||
|
seed: '4567 ... 0987',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '14',
|
||||||
|
check: true,
|
||||||
|
filed: 'Document ID',
|
||||||
|
data: '1233425345',
|
||||||
|
status: 'Correct',
|
||||||
|
seed: '1234 ... 1234',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const [selectAll, setSelectAll] = useState(false);
|
||||||
|
const [marked, setMarked] = useState([]);
|
||||||
|
const [selectedList, setSelectedList] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setSelectedList(validateData);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleSelectAll = () => {
|
||||||
|
setSelectAll(!selectAll);
|
||||||
|
setMarked(selectedList.map(li => li.id));
|
||||||
|
if (selectAll) {
|
||||||
|
setMarked([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClick = e => {
|
||||||
|
const { id, checked } = e.target;
|
||||||
|
setSelectAll(false);
|
||||||
|
setMarked([...marked, id]);
|
||||||
|
if (!checked) {
|
||||||
|
setMarked(marked.filter(item => item !== id));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-fit">
|
||||||
|
<div>
|
||||||
|
{/* Table */}
|
||||||
|
<div className="overflow-x-auto">
|
||||||
|
<table className="table-auto w-fit">
|
||||||
|
{/* 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">
|
||||||
|
<div className="flex items-center">
|
||||||
|
<label className="inline-flex">
|
||||||
|
<span className="sr-only">Select all</span>
|
||||||
|
<input className="form-checkbox" type="checkbox" checked={selectAll} onChange={handleSelectAll} />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th className="px-2 first:pl-5 pr-[136px] py-3 whitespace-nowrap">
|
||||||
|
<div className="font-semibold text-left">FIELD</div>
|
||||||
|
</th>
|
||||||
|
<th className="px-2 first:pl-5 pr-[154px] py-3 whitespace-nowrap">
|
||||||
|
<div className="font-semibold text-left">DATA</div>
|
||||||
|
</th>
|
||||||
|
<th className="min-w-[191px] px-2 first:pl-5 pr-[168px] py-3 whitespace-nowrap">
|
||||||
|
<div className="pl-7 font-semibold text-left">SEED</div>
|
||||||
|
</th>
|
||||||
|
<th className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap">
|
||||||
|
<div className="pl-2 font-semibold text-left">STATUS</div>
|
||||||
|
</th>
|
||||||
|
<th className="px-2 first:pl-5 last:pr-5 py-3 whitespace-nowrap" />
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{/* Table body */}
|
||||||
|
<tbody className="text-sm divide-y divide-slate-200 border-b border-slate-200">
|
||||||
|
{selectedList.map((data) => {
|
||||||
|
return (
|
||||||
|
<ValidateTableItem
|
||||||
|
key={data.id}
|
||||||
|
id={data.id}
|
||||||
|
filed={data.filed}
|
||||||
|
data={data.data}
|
||||||
|
status={data.status}
|
||||||
|
seed={data.seed}
|
||||||
|
check={data.check}
|
||||||
|
handleClick={handleClick}
|
||||||
|
isChecked={marked.includes(data.id)}
|
||||||
|
setValidatePanelOpen={setValidatePanelOpen}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ValidateTable;
|
||||||
39
src/partials/validationlog/ValidateRoadMap.jsx
Normal file
39
src/partials/validationlog/ValidateRoadMap.jsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import ValidationSeasonItem from "./ValidationSeasonItem";
|
||||||
|
import ValidationUsersImg from "./ValidationUsersImg";
|
||||||
|
|
||||||
|
function ValidateRoadMap({ season }) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<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">{season.name}</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}/>
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div className="text-slate-400">·</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
{/* 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}/>
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ValidateRoadMap;
|
||||||
30
src/partials/validationlog/ValidationSeasonItem.jsx
Normal file
30
src/partials/validationlog/ValidationSeasonItem.jsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
function ValidationSeasonItem({ length, item, index }) {
|
||||||
|
return (
|
||||||
|
<li className="relative py-2">
|
||||||
|
<div className="flex items-center mb-1">
|
||||||
|
{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">
|
||||||
|
<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"/>}
|
||||||
|
</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>}
|
||||||
|
</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>
|
||||||
|
<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>
|
||||||
|
<a className="cursor-pointer pl-9 font-normal text-sm text-indigo-500 hover:text-indigo-600">Explore -></a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ValidationSeasonItem
|
||||||
11
src/partials/validationlog/ValidationUsersImg.jsx
Normal file
11
src/partials/validationlog/ValidationUsersImg.jsx
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
function ValidationUsersImg({ image }) {
|
||||||
|
return (
|
||||||
|
<a className="block" href="#0">
|
||||||
|
<img className="rounded-full border-2 border-white box-content" src={image.img} width="28" alt={image.img} height="28"/>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ValidationUsersImg
|
||||||
Reference in New Issue
Block a user