Added search functionality
This commit is contained in:
parent
2f74539d36
commit
969e337e9f
108
css/main.css
108
css/main.css
@ -2,7 +2,7 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: "Times New Roman", Times, serif;
|
font-family: "Roboto", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
@ -52,23 +52,58 @@ button {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=date] {
|
.wrap-around {
|
||||||
padding: 1rem 0.8rem;
|
overflow-wrap: break-word;
|
||||||
font-size: inherit;
|
word-wrap: break-word;
|
||||||
background-color: rgba(var(--text-color), 0.06);
|
word-break: break-word;
|
||||||
border: none;
|
-webkit-hyphens: auto;
|
||||||
border-radius: 0.3rem;
|
hyphens: auto;
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#details {
|
.observe-empty-state:empty {
|
||||||
align-content: flex-start;
|
display: none;
|
||||||
padding: 1.5rem;
|
|
||||||
display: grid;
|
|
||||||
gap: 1rem;
|
|
||||||
}
|
}
|
||||||
#details * {
|
|
||||||
font-family: "Roboto", sans-serif;
|
.observe-empty-state:not(:empty) ~ .empty-state {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#home > * {
|
||||||
|
width: min(100%, 56rem);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
#home h1 {
|
||||||
|
padding: 1rem;
|
||||||
|
padding-top: 10vmax;
|
||||||
|
font-size: max(1.8rem, 4vw);
|
||||||
|
text-align: center;
|
||||||
|
background: linear-gradient(135deg, #fa00ff, #00e0ff 50%, #fa00ff);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-size: 200%;
|
||||||
|
animation: gradient 20s ease infinite alternate-reverse;
|
||||||
|
}
|
||||||
|
@-webkit-keyframes gradient {
|
||||||
|
0% {
|
||||||
|
background-position: 0% 50%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes gradient {
|
||||||
|
0% {
|
||||||
|
background-position: 0% 50%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#home header {
|
||||||
|
width: 100%;
|
||||||
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
margin-bottom: -2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#cert_sec {
|
#cert_sec {
|
||||||
@ -76,11 +111,27 @@ input[type=date] {
|
|||||||
font-family: "intern";
|
font-family: "intern";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#search_certificates {
|
||||||
|
position: -webkit-sticky;
|
||||||
|
position: sticky;
|
||||||
|
top: 1rem;
|
||||||
|
width: min(24rem, 100% - 2rem);
|
||||||
|
margin: 0 auto;
|
||||||
|
--border-radius: 0.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
--padding: 1rem 1.2rem;
|
||||||
|
background-color: rgba(var(--foreground-color), 1);
|
||||||
|
box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.1);
|
||||||
|
border: solid thin rgba(var(--text-color), 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
#issued_cert_list {
|
#issued_cert_list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
padding: 1.5rem;
|
padding: 1rem;
|
||||||
|
padding-bottom: 4rem;
|
||||||
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cert-card {
|
.cert-card {
|
||||||
@ -93,12 +144,25 @@ input[type=date] {
|
|||||||
.cert-card h4 {
|
.cert-card h4 {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
.cert-card > * {
|
.cert-card p {
|
||||||
font-family: "Roboto", sans-serif;
|
font-size: 0.9rem;
|
||||||
|
color: rgba(var(--text-color), 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
#certificate {
|
||||||
#main {
|
display: flex;
|
||||||
display: grid;
|
align-items: center;
|
||||||
}
|
justify-content: center;
|
||||||
|
}
|
||||||
|
#certificate * {
|
||||||
|
font-family: "Times New Roman", Times, serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#certificate_svg {
|
||||||
|
flex-shrink: 0;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none !important;
|
||||||
}
|
}
|
||||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
@ -1 +1 @@
|
|||||||
*{padding:0;margin:0;box-sizing:border-box;font-family:"Times New Roman",Times,serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%}body{--accent-color: #3d5afe;--secondary-color: #ffac2e;--text-color: 34, 34, 34;--foreground-color: 252, 253, 255;--background-color: 241, 243, 248;--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: rgb(220, 165, 0);color:rgba(var(--text-color), 1);background-color:rgba(var(--background-color), 1)}body[data-theme=dark]{--accent-color: #92a2ff;--secondary-color: #d60739;--text-color: 200, 200, 200;--foreground-color: 27, 28, 29;--background-color: 21, 22, 22;--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: rgb(255, 213, 5)}body[data-theme=dark] ::-webkit-calendar-picker-indicator{filter:invert(1)}button{padding:1rem;font-size:inherit;background-color:var(--accent-color);border:none;border-radius:.3rem;color:#fff;font-weight:500;cursor:pointer}input[type=date]{padding:1rem .8rem;font-size:inherit;background-color:rgba(var(--text-color), 0.06);border:none;border-radius:.3rem;font-weight:500}#details{align-content:flex-start;padding:1.5rem;display:grid;gap:1rem}#details *{font-family:"Roboto",sans-serif}#cert_sec{padding:1.5rem;font-family:"intern"}#issued_cert_list{display:flex;flex-direction:column;gap:1rem;padding:1.5rem}.cert-card{display:grid;gap:.5rem;padding:1rem;background-color:rgba(var(--text-color), 0.06);border-radius:.5rem}.cert-card h4{font-size:1.2rem}.cert-card>*{font-family:"Roboto",sans-serif}@media(min-width: 768px){#main{display:grid}}
|
*{padding:0;margin:0;box-sizing:border-box;font-family:"Roboto",sans-serif}:root{font-size:clamp(1rem,1.2vmax,1.2rem)}html,body{height:100%}body{--accent-color: #3d5afe;--secondary-color: #ffac2e;--text-color: 34, 34, 34;--foreground-color: 252, 253, 255;--background-color: 241, 243, 248;--danger-color: rgb(255, 75, 75);--green: #1cad59;--yellow: rgb(220, 165, 0);color:rgba(var(--text-color), 1);background-color:rgba(var(--background-color), 1)}body[data-theme=dark]{--accent-color: #92a2ff;--secondary-color: #d60739;--text-color: 200, 200, 200;--foreground-color: 27, 28, 29;--background-color: 21, 22, 22;--danger-color: rgb(255, 106, 106);--green: #00e676;--yellow: rgb(255, 213, 5)}body[data-theme=dark] ::-webkit-calendar-picker-indicator{filter:invert(1)}button{padding:1rem;font-size:inherit;background-color:var(--accent-color);border:none;border-radius:.3rem;color:#fff;font-weight:500;cursor:pointer}.wrap-around{overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;-webkit-hyphens:auto;hyphens:auto}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}#home>*{width:min(100%,56rem);margin:0 auto}#home h1{padding:1rem;padding-top:10vmax;font-size:max(1.8rem,4vw);text-align:center;background:linear-gradient(135deg, #fa00ff, #00e0ff 50%, #fa00ff);-webkit-background-clip:text;-webkit-text-fill-color:rgba(0,0,0,0);background-size:200%;animation:gradient 20s ease infinite alternate-reverse}@-webkit-keyframes gradient{0%{background-position:0% 50%}100%{background-position:100% 50%}}@keyframes gradient{0%{background-position:0% 50%}100%{background-position:100% 50%}}#home header{width:100%;background-color:rgba(var(--text-color), 0.06);padding-bottom:2rem;margin-bottom:-2rem}#cert_sec{padding:1.5rem;font-family:"intern"}#search_certificates{position:-webkit-sticky;position:sticky;top:1rem;width:min(24rem,100% - 2rem);margin:0 auto;--border-radius: 0.5rem;border-radius:.5rem;--padding: 1rem 1.2rem;background-color:rgba(var(--foreground-color), 1);box-shadow:0 .5rem 1.5rem rgba(0,0,0,.1);border:solid thin rgba(var(--text-color), 0.2)}#issued_cert_list{display:flex;flex-direction:column;gap:1rem;padding:1rem;padding-bottom:4rem;margin-top:1rem}.cert-card{display:grid;gap:.5rem;padding:1rem;background-color:rgba(var(--text-color), 0.06);border-radius:.5rem}.cert-card h4{font-size:1.2rem}.cert-card p{font-size:.9rem;color:rgba(var(--text-color), 0.9)}#certificate{display:flex;align-items:center;justify-content:center}#certificate *{font-family:"Times New Roman",Times,serif}#certificate_svg{flex-shrink:0;background-color:#fff}.hidden{display:none !important}
|
||||||
@ -2,7 +2,7 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: "Times New Roman", Times, serif;
|
font-family: "Roboto", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
@ -51,32 +51,74 @@ button {
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
input[type="date"] {
|
.wrap-around {
|
||||||
padding: 1rem 0.8rem;
|
overflow-wrap: break-word;
|
||||||
font-size: inherit;
|
word-wrap: break-word;
|
||||||
background-color: rgba(var(--text-color), 0.06);
|
word-break: break-word;
|
||||||
border: none;
|
hyphens: auto;
|
||||||
border-radius: 0.3rem;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
#details {
|
|
||||||
align-content: flex-start;
|
.observe-empty-state:empty {
|
||||||
padding: 1.5rem;
|
display: none;
|
||||||
display: grid;
|
}
|
||||||
gap: 1rem;
|
|
||||||
* {
|
.observe-empty-state:not(:empty) ~ .empty-state {
|
||||||
font-family: "Roboto", sans-serif;
|
display: none;
|
||||||
|
}
|
||||||
|
#home {
|
||||||
|
& > * {
|
||||||
|
width: min(100%, 56rem);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
padding: 1rem;
|
||||||
|
padding-top: 10vmax;
|
||||||
|
font-size: max(1.8rem, 4vw);
|
||||||
|
text-align: center;
|
||||||
|
background: linear-gradient(135deg, #fa00ff, #00e0ff 50%, #fa00ff);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-size: 200%;
|
||||||
|
animation: gradient 20s ease infinite alternate-reverse;
|
||||||
|
}
|
||||||
|
@keyframes gradient {
|
||||||
|
0% {
|
||||||
|
background-position: 0% 50%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
width: 100%;
|
||||||
|
background-color: rgba(var(--text-color), 0.06);
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
margin-bottom: -2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#cert_sec {
|
#cert_sec {
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
font-family: "intern";
|
font-family: "intern";
|
||||||
}
|
}
|
||||||
|
#search_certificates {
|
||||||
|
position: sticky;
|
||||||
|
top: 1rem;
|
||||||
|
width: min(24rem, calc(100% - 2rem));
|
||||||
|
margin: 0 auto;
|
||||||
|
--border-radius: 0.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
--padding: 1rem 1.2rem;
|
||||||
|
background-color: rgba(var(--foreground-color), 1);
|
||||||
|
box-shadow: 0 0.5rem 1.5rem rgba(0 0 0 /0.1);
|
||||||
|
border: solid thin rgba(var(--text-color), 0.2);
|
||||||
|
}
|
||||||
#issued_cert_list {
|
#issued_cert_list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
padding: 1.5rem;
|
padding: 1rem;
|
||||||
|
padding-bottom: 4rem;
|
||||||
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
.cert-card {
|
.cert-card {
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -87,12 +129,26 @@ input[type="date"] {
|
|||||||
h4 {
|
h4 {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
& > * {
|
p {
|
||||||
font-family: "Roboto", sans-serif;
|
font-size: 0.9rem;
|
||||||
|
color: rgba(var(--text-color), 0.9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#certificate {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
* {
|
||||||
|
font-family: "Times New Roman", Times, serif;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#certificate_svg {
|
||||||
|
flex-shrink: 0;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
#main {
|
}
|
||||||
display: grid;
|
|
||||||
}
|
.hidden {
|
||||||
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|||||||
238
index.html
238
index.html
@ -32,11 +32,24 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<section>
|
<section id="home" class="page">
|
||||||
<ul id="issued_cert_list"></ul>
|
<header>
|
||||||
|
<h1>RanchiMall Certificates</h1>
|
||||||
|
</header>
|
||||||
|
<sm-input id="search_certificates" placeholder="Search FLO address or name" type="search">
|
||||||
|
<svg slot="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||||
|
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
|
||||||
|
class="feather feather-search">
|
||||||
|
<circle cx="11" cy="11" r="8"></circle>
|
||||||
|
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||||
|
</svg>
|
||||||
|
</sm-input>
|
||||||
|
<ul id="issued_cert_list" class="observe-empty-state"></ul>
|
||||||
|
<div class="empty-state">
|
||||||
|
<h2>No related certificates issued yet</h2>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<main id="main">
|
<section id="certificate" class="page hidden">
|
||||||
<section>
|
|
||||||
<svg id="certificate_svg" width="1400" height="980" viewBox="0 0 1400 980" fill="none"
|
<svg id="certificate_svg" width="1400" height="980" viewBox="0 0 1400 980" fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
<g id="certificate">
|
<g id="certificate">
|
||||||
@ -63,8 +76,8 @@
|
|||||||
font-size="18">
|
font-size="18">
|
||||||
<tspan x="490.187" y="310.073">RanchiMall, a blockchain incorporated entity certifies that </tspan>
|
<tspan x="490.187" y="310.073">RanchiMall, a blockchain incorporated entity certifies that </tspan>
|
||||||
</text>
|
</text>
|
||||||
<text id="issue_date" fill="#373737" xml:space="preserve" style="white-space: pre"
|
<text id="issue_date" fill="#373737" xml:space="preserve" style="white-space: pre" font-family="Times New Roman"
|
||||||
font-family="Times New Roman" font-size="18">
|
font-size="18">
|
||||||
<tspan x="647.493" y="253.573">16th Dec 2020</tspan>
|
<tspan x="647.493" y="253.573">16th Dec 2020</tspan>
|
||||||
</text>
|
</text>
|
||||||
<g id="Frame_2" clip-path="url(#clip1_60_2)">
|
<g id="Frame_2" clip-path="url(#clip1_60_2)">
|
||||||
@ -83,8 +96,8 @@
|
|||||||
<tspan x="506.293" y="217.646">CERTIFICATE TYPE</tspan>
|
<tspan x="506.293" y="217.646">CERTIFICATE TYPE</tspan>
|
||||||
</text>
|
</text>
|
||||||
<rect id="Rectangle 69" x="62" y="57" width="1277" height="865" rx="12" stroke="#5B21FF" stroke-width="8" />
|
<rect id="Rectangle 69" x="62" y="57" width="1277" height="865" rx="12" stroke="#5B21FF" stroke-width="8" />
|
||||||
<text id="cert_data" fill="#333333" xml:space="preserve" style="white-space: pre"
|
<text id="cert_data" fill="#333333" xml:space="preserve" style="white-space: pre" font-family="Times New Roman"
|
||||||
font-family="Times New Roman" font-size="18">
|
font-size="18">
|
||||||
</text>
|
</text>
|
||||||
<g id="Group 12">
|
<g id="Group 12">
|
||||||
<text id="FLO INCORPORATION ID" fill="#353535" xml:space="preserve" style="white-space: pre"
|
<text id="FLO INCORPORATION ID" fill="#353535" xml:space="preserve" style="white-space: pre"
|
||||||
@ -133,22 +146,7 @@
|
|||||||
</clipPath>
|
</clipPath>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
<section id="details">
|
|
||||||
<!-- <h3>Fill the details</h3>
|
|
||||||
<sm-input id="cert_type_field" data-bind="name" placeholder="Certificate type" animate></sm-input>
|
|
||||||
<sm-input id="name_field" data-bind="name" placeholder="Name" animate></sm-input>
|
|
||||||
<input type="date" id="issue_date_field" data-bind="issue_date" placeholder="Issue date">
|
|
||||||
<sm-input id="intern_id_field" data-bind="intern_flo_id" placeholder="Intern FLO ID" animate>
|
|
||||||
</sm-input>
|
|
||||||
<sm-input id="flo_link" data-bind="intern_flo_id" placeholder="FLO trasansaction link" animate>
|
|
||||||
</sm-input>
|
|
||||||
<sm-textarea id="cert_text" placeholder="data" rows="4"></sm-textarea> -->
|
|
||||||
<button id="download_btn">Download</button>
|
|
||||||
</section>
|
|
||||||
</main>
|
|
||||||
<script>
|
<script>
|
||||||
// Use instead of document.getElementById
|
// Use instead of document.getElementById
|
||||||
const domRefs = {}
|
const domRefs = {}
|
||||||
@ -173,7 +171,6 @@
|
|||||||
const appState = {
|
const appState = {
|
||||||
params: {},
|
params: {},
|
||||||
}
|
}
|
||||||
const generalPages = ['sign_up', 'sign_in', 'loading', 'landing']
|
|
||||||
function routeTo(targetPage, options = {}) {
|
function routeTo(targetPage, options = {}) {
|
||||||
const { firstLoad } = options
|
const { firstLoad } = options
|
||||||
const routingAnimation = { in: slideInUp, out: slideOutUp }
|
const routingAnimation = { in: slideInUp, out: slideOutUp }
|
||||||
@ -182,12 +179,8 @@
|
|||||||
let searchParams
|
let searchParams
|
||||||
let params
|
let params
|
||||||
if (targetPage === '') {
|
if (targetPage === '') {
|
||||||
try {
|
pageId = 'home'
|
||||||
if (floDapps.user.id)
|
history.replaceState(null, null, '#/home');
|
||||||
pageId = 'dashboard_page'
|
|
||||||
} catch (e) {
|
|
||||||
pageId = 'landing'
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (targetPage.includes('/')) {
|
if (targetPage.includes('/')) {
|
||||||
if (targetPage.includes('?')) {
|
if (targetPage.includes('?')) {
|
||||||
@ -201,16 +194,7 @@
|
|||||||
pageId = targetPage
|
pageId = targetPage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!getRef(pageId)?.classList.contains('page')) return
|
||||||
if (!document.querySelector(`#${pageId}`)?.classList.contains('inner-page')) return
|
|
||||||
try {
|
|
||||||
if (floDapps.user.id && (generalPages.includes(pageId))) {
|
|
||||||
history.replaceState(null, null, '#/dashboard_page');
|
|
||||||
pageId = 'dashboard_page'
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (!(generalPages.includes(pageId))) return
|
|
||||||
}
|
|
||||||
appState.currentPage = pageId
|
appState.currentPage = pageId
|
||||||
|
|
||||||
if (searchParams) {
|
if (searchParams) {
|
||||||
@ -220,19 +204,14 @@
|
|||||||
if (params)
|
if (params)
|
||||||
appState.params = params
|
appState.params = params
|
||||||
switch (pageId) {
|
switch (pageId) {
|
||||||
case 'landing':
|
case 'home':
|
||||||
|
renderElem(getRef('issued_cert_list'), html`${[...floGlobals.validCerts.values()].map(cert => render.issuedCertCard(cert))}`)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (appState.lastPage !== pageId) {
|
if (appState.lastPage !== pageId) {
|
||||||
if (document.querySelector('.nav-list__item--active'))
|
if (document.querySelector('.nav-list__item--active'))
|
||||||
document.querySelector('.nav-list__item--active').classList.remove('nav-list__item--active');
|
document.querySelector('.nav-list__item--active').classList.remove('nav-list__item--active');
|
||||||
const targetListItem = [...document.querySelectorAll(`a.nav-list__item`)].find(item => item.href.includes(pageId))
|
const targetListItem = [...document.querySelectorAll(`a.nav-list__item`)].find(item => item.href.includes(pageId))
|
||||||
if (targetListItem) {
|
|
||||||
targetListItem.classList.add('nav-list__item--active')
|
|
||||||
getRef('main_nav').classList.remove('hide-on-mobile')
|
|
||||||
} else {
|
|
||||||
getRef('main_nav').classList.add('hide-on-mobile')
|
|
||||||
}
|
|
||||||
document.querySelectorAll('.page').forEach(page => page.classList.add('hidden'))
|
document.querySelectorAll('.page').forEach(page => page.classList.add('hidden'))
|
||||||
getRef(pageId).closest('.page').classList.remove('hidden')
|
getRef(pageId).closest('.page').classList.remove('hidden')
|
||||||
let ogOverflow = getRef(pageId).parentNode.style.overflow
|
let ogOverflow = getRef(pageId).parentNode.style.overflow
|
||||||
@ -243,10 +222,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
getRef(pageId).classList.remove('hidden')
|
getRef(pageId).classList.remove('hidden')
|
||||||
|
if (pageId === 'certificate') {
|
||||||
|
if (params) {
|
||||||
|
render.certificate(params.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
getRef(pageId).animate(routingAnimation.in, { duration: floGlobals.prefersReducedMotion ? 0 : 150, fill: 'forwards', easing: 'ease' }).onfinish = (e) => {
|
getRef(pageId).animate(routingAnimation.in, { duration: floGlobals.prefersReducedMotion ? 0 : 150, fill: 'forwards', easing: 'ease' }).onfinish = (e) => {
|
||||||
getRef(pageId).parentNode.style.overflow = ogOverflow;
|
getRef(pageId).parentNode.style.overflow = ogOverflow;
|
||||||
switch (pageId) {
|
switch (pageId) {
|
||||||
case 'sign_in':
|
case 'certificate':
|
||||||
|
convertSvgToPdf(getRef('certificate_svg'))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
appState.lastPage = pageId
|
appState.lastPage = pageId
|
||||||
@ -256,6 +241,86 @@
|
|||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
const { html, render: renderElem } = uhtml;
|
const { html, render: renderElem } = uhtml;
|
||||||
|
const slideInLeft = [
|
||||||
|
{
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateX(1rem)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateX(0)'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const slideOutLeft = [
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateX(0)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateX(-1rem)'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const slideInRight = [
|
||||||
|
{
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateX(-1rem)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateX(0)'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const slideOutRight = [
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateX(0)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateX(1rem)'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const slideInDown = [
|
||||||
|
{
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(-1rem)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const slideOutDown = [
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(1rem)'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const slideInUp = [
|
||||||
|
{
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(1rem)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
const slideOutUp = [
|
||||||
|
{
|
||||||
|
opacity: 1,
|
||||||
|
transform: 'translateY(0)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
opacity: 0,
|
||||||
|
transform: 'translateY(-1rem)'
|
||||||
|
},
|
||||||
|
]
|
||||||
function getFormattedTime(timestamp, format) {
|
function getFormattedTime(timestamp, format) {
|
||||||
try {
|
try {
|
||||||
timestamp = parseInt(timestamp)
|
timestamp = parseInt(timestamp)
|
||||||
@ -290,16 +355,38 @@
|
|||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
window.addEventListener('hashchange', e => routeTo(window.location.hash))
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
const { jsPDF } = window.jspdf;
|
readTx().then(() => {
|
||||||
const { svg2pdf } = window.svg2pdf;
|
routeTo(window.location.hash);
|
||||||
|
})
|
||||||
|
getRef('search_certificates').addEventListener('input', e => {
|
||||||
|
const searchQuery = e.target.value.toLowerCase();
|
||||||
|
const filteredCerts = [...floGlobals.validCerts.values()].filter(cert => {
|
||||||
|
return cert.name.toLowerCase().includes(searchQuery) || cert.floId.toLowerCase().includes(searchQuery)
|
||||||
|
})
|
||||||
|
// sort filtered by relevance
|
||||||
|
filteredCerts.sort((a, b) => {
|
||||||
|
if (a.name.toLowerCase().includes(searchQuery) && b.name.toLowerCase().includes(searchQuery)) {
|
||||||
|
return a.name.toLowerCase().indexOf(searchQuery) - b.name.toLowerCase().indexOf(searchQuery)
|
||||||
|
}
|
||||||
|
if (a.name.toLowerCase().includes(searchQuery)) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if (b.name.toLowerCase().includes(searchQuery)) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
renderElem(getRef('issued_cert_list'), html`${filteredCerts.map(cert => render.issuedCertCard(cert))}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
function convertSvgToPdf(element) {
|
function convertSvgToPdf(element) {
|
||||||
const margin = 5
|
const margin = 5
|
||||||
const sizeArray = new Array(2)
|
const sizeArray = new Array(2)
|
||||||
sizeArray[0] = 1400 + 2 * margin
|
sizeArray[0] = 1400 + 2 * margin
|
||||||
sizeArray[1] = 980 + 2 * margin
|
sizeArray[1] = 980 + 2 * margin
|
||||||
// eslint-disable-next-line no-undef,new-cap
|
const jsPdf = new window.jspdf.jsPDF({
|
||||||
const jsPdf = new jsPDF({
|
|
||||||
orientation: sizeArray[0] > sizeArray[1] ? 'l' : 'p',
|
orientation: sizeArray[0] > sizeArray[1] ? 'l' : 'p',
|
||||||
unit: 'pt',
|
unit: 'pt',
|
||||||
format: sizeArray,
|
format: sizeArray,
|
||||||
@ -315,22 +402,11 @@
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// save the created pdf
|
// save the created pdf
|
||||||
jsPdf.save('myPDF.pdf')
|
// jsPdf.save('RanchiMallCertificate.pdf')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
getRef('download_btn').addEventListener('click', e => {
|
|
||||||
var myPDF = convertSvgToPdf(getRef('certificate_svg'))
|
|
||||||
})
|
|
||||||
getRef('issued_cert_list').addEventListener('click', e => {
|
|
||||||
if (e.target.closest('button')) {
|
|
||||||
const txId = e.target.closest('button').getAttribute('data-txid')
|
|
||||||
render.certificate(txId)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
readTx()
|
|
||||||
}
|
|
||||||
function alignTextCenter(element) {
|
function alignTextCenter(element) {
|
||||||
element.setAttribute('x', `${700 - element.getBoundingClientRect().width / 2}`)
|
element.setAttribute('x', 700 - element.getBoundingClientRect().width / 2)
|
||||||
}
|
}
|
||||||
// return string between two strings
|
// return string between two strings
|
||||||
function getBetween(str, start, end) {
|
function getBetween(str, start, end) {
|
||||||
@ -340,6 +416,10 @@
|
|||||||
function getFirstThreeWords(str) {
|
function getFirstThreeWords(str) {
|
||||||
return str.split(' ').slice(0, 3).join(' ')
|
return str.split(' ').slice(0, 3).join(' ')
|
||||||
}
|
}
|
||||||
|
// get all words after given word including the word
|
||||||
|
function removeWordsBefore(str, word) {
|
||||||
|
return str.substring(str.indexOf(word));
|
||||||
|
}
|
||||||
// split string into lines of max characters per line without breaking words
|
// split string into lines of max characters per line without breaking words
|
||||||
function splitIntoLines(str, maxChars = 132) {
|
function splitIntoLines(str, maxChars = 132) {
|
||||||
let lines = []
|
let lines = []
|
||||||
@ -358,21 +438,17 @@
|
|||||||
}
|
}
|
||||||
const render = {
|
const render = {
|
||||||
issuedCertCard(details) {
|
issuedCertCard(details) {
|
||||||
const { floData, txid } = details
|
const { floData, txid, name, floId } = details
|
||||||
const name = getBetween(floData, 'certifies that', 'FLO ID')
|
|
||||||
const floId = floData.match(/\b\w{30,36}\b/)
|
|
||||||
return html`
|
return html`
|
||||||
<li class="cert-card">
|
<li class="cert-card">
|
||||||
<h4>${name}</h4>
|
<h4>${name}</h4>
|
||||||
<p>${floId}</p>
|
<p class="wrap-around">${floId}</p>
|
||||||
<button data-txid=${txid}>View</button>
|
<a href=${`#/certificate?id=${txid}`}>View</a>
|
||||||
</li>
|
</li>
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
certificate(txid) {
|
certificate(txid) {
|
||||||
const { floData, time } = floGlobals.validCerts.get(txid)
|
const { floData, time, name, floId } = floGlobals.validCerts.get(txid)
|
||||||
const name = getBetween(floData, 'certifies that', 'FLO ID')
|
|
||||||
const floId = floData.match(/\b\w{30,36}\b/)
|
|
||||||
getRef('certificate_type').firstElementChild.textContent = getFirstThreeWords(floData).toUpperCase();
|
getRef('certificate_type').firstElementChild.textContent = getFirstThreeWords(floData).toUpperCase();
|
||||||
alignTextCenter(getRef('certificate_type').firstElementChild)
|
alignTextCenter(getRef('certificate_type').firstElementChild)
|
||||||
getRef('main_name').firstElementChild.textContent = name.toUpperCase();
|
getRef('main_name').firstElementChild.textContent = name.toUpperCase();
|
||||||
@ -382,7 +458,7 @@
|
|||||||
getRef('intern_flo_id').firstElementChild.textContent = floId
|
getRef('intern_flo_id').firstElementChild.textContent = floId
|
||||||
alignTextCenter(getRef('intern_flo_id').firstElementChild)
|
alignTextCenter(getRef('intern_flo_id').firstElementChild)
|
||||||
getRef('cert_data').innerHTML = ''
|
getRef('cert_data').innerHTML = ''
|
||||||
splitIntoLines(floData).forEach((line, index) => {
|
splitIntoLines(removeWordsBefore(floData, 'worked')).forEach((line, index) => {
|
||||||
let tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan')
|
let tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan')
|
||||||
tspan.textContent = line
|
tspan.textContent = line
|
||||||
tspan.setAttribute('x', '0')
|
tspan.setAttribute('x', '0')
|
||||||
@ -418,20 +494,26 @@
|
|||||||
getRef('cert_qr').appendChild(svgNode);
|
getRef('cert_qr').appendChild(svgNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
floGlobals.validCerts = new Map()
|
floGlobals.validCerts = new Map()
|
||||||
function readTx() {
|
function readTx() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
floBlockchainAPI.readAllTxs('FFCpiaZi31TpbYw5q5VNk8qJMeDiTLgsrE').then(res => {
|
floBlockchainAPI.readAllTxs('FFCpiaZi31TpbYw5q5VNk8qJMeDiTLgsrE').then(res => {
|
||||||
res.forEach(tx => {
|
res.forEach(tx => {
|
||||||
const { vin, vout, time, floData } = tx
|
const { vin, vout, time, floData } = tx
|
||||||
const iVerify = vin.some(i => i.addr === floGlobals.RM_CertificateIssuer_id);
|
const iVerify = vin.some(i => i.addr === floGlobals.RM_CertificateIssuer_id);
|
||||||
const oVerify = vout.some(o => [floGlobals.RMincorporationID, floGlobals.RIBC_id].includes(o.scriptPubKey.addresses[0]));
|
const oVerify = vout.some(o => [floGlobals.RMincorporationID, floGlobals.RIBC_id].includes(o.scriptPubKey.addresses[0]));
|
||||||
const cVerify = tx.floData.startsWith('CERTIFICATE OF')
|
const cVerify = tx.floData.startsWith('CERTIFICATE OF')
|
||||||
const hasFloId = /\b\w{30,36}\b/.test(floData)
|
const floId = floData.match(/\b\w{30,36}\b/)?.[0]
|
||||||
if (iVerify && oVerify && cVerify && hasFloId) {
|
if (iVerify && oVerify && cVerify && floId) {
|
||||||
floGlobals.validCerts.set(tx.txid, tx)
|
const name = getBetween(floData, 'certifies that', 'FLO ID')
|
||||||
|
floGlobals.validCerts.set(tx.txid, { name, ...tx, floId })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
renderElem(getRef('issued_cert_list'), html`${[...floGlobals.validCerts.values()].map(cert => render.issuedCertCard(cert))}`)
|
resolve()
|
||||||
|
}).catch(err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user