mirror of
https://github.com/tornadocash/trusted-setup-server.git
synced 2024-11-22 01:46:52 +01:00
add table layout
-change route to make contribution
This commit is contained in:
parent
0de5c68d56
commit
213a7879fd
1
assets/img/icons/arrow-left.svg
Normal file
1
assets/img/icons/arrow-left.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="16"><path fill-rule="evenodd" d="M8.713 1.691L2.404 8l6.309 6.309a.992.992 0 1 1-1.404 1.404L.353 8.758C.332 8.74.306 8.733.287 8.713A.984.984 0 0 1-.002 8a.984.984 0 0 1 .289-.713c.019-.02.045-.027.066-.044L7.309.287a.992.992 0 1 1 1.404 1.404z"/></svg>
|
After Width: | Height: | Size: 312 B |
1
assets/img/icons/arrow-right.svg
Normal file
1
assets/img/icons/arrow-right.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="16"><path fill-rule="evenodd" d="M8.713 8.713c-.019.02-.045.027-.066.045l-6.956 6.955a.992.992 0 1 1-1.404-1.404L6.596 8 .287 1.691A.992.992 0 1 1 1.691.287l6.956 6.956c.021.017.047.024.066.044A.984.984 0 0 1 9.002 8a.984.984 0 0 1-.289.713z"/></svg>
|
After Width: | Height: | Size: 308 B |
1
assets/img/icons/emoticon-sad.svg
Normal file
1
assets/img/icons/emoticon-sad.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><path fill="#eee" d="M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12M15.5,8C16.3,8 17,8.7 17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,9.5C14,8.7 14.7,8 15.5,8M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M12,14C13.75,14 15.29,14.72 16.19,15.81L14.77,17.23C14.32,16.5 13.25,16 12,16C10.75,16 9.68,16.5 9.23,17.23L7.81,15.81C8.71,14.72 10.25,14 12,14Z" /></svg>
|
After Width: | Height: | Size: 629 B |
3
assets/img/icons/search.svg
Normal file
3
assets/img/icons/search.svg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
|
||||||
|
<path fill="#94FEBF" fill-rule="evenodd" d="M15.678 15.678a1.045 1.045 0 0 1-1.478 0l-3.06-3.06A6.941 6.941 0 0 1 7 14a7 7 0 1 1 7-7 6.941 6.941 0 0 1-1.382 4.14l3.06 3.06c.408.408.408 1.07 0 1.478zM7 2a5 5 0 1 0 .001 10.001A5 5 0 0 0 7 2z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 318 B |
@ -78,6 +78,30 @@
|
|||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.is-icon {
|
||||||
|
padding:0;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
path:not(.no-hover) {
|
||||||
|
fill: #87feb7;
|
||||||
|
transition: fill .15s ease-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus:not(:active) {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.box {
|
.box {
|
||||||
@ -155,6 +179,34 @@
|
|||||||
.label {
|
.label {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.is-horizontal {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
@include mobile {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-label.is-normal {
|
||||||
|
padding-top: 0;
|
||||||
|
margin-right: 1.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.currently {
|
||||||
|
font-size: .85rem;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: $primary;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: $weight-bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-bottom: $block-spacing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,3 +249,249 @@
|
|||||||
to {
|
to {
|
||||||
transform: rotate(0deg); }
|
transform: rotate(0deg); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.b-table {
|
||||||
|
.table {
|
||||||
|
a {
|
||||||
|
color: $primary;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: $weight-normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
border-color: rgba($primary, .5)
|
||||||
|
}
|
||||||
|
|
||||||
|
td, th {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody {
|
||||||
|
tr {
|
||||||
|
&:last-child {
|
||||||
|
td {
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.is-selected) {
|
||||||
|
&:nth-child(odd) {
|
||||||
|
background-color: $table-striped-row-even-background-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $table-row-hover-background-color;
|
||||||
|
&:nth-child(odd) {
|
||||||
|
background-color: $table-striped-row-even-hover-background-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.is-selected).is-empty {
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown.is-expanded {
|
||||||
|
min-width: 75px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
|
||||||
|
&-emoticon-sad {
|
||||||
|
background-image: url('../img/icons/emoticon-sad.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-48px {
|
||||||
|
height: 48px;
|
||||||
|
width: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-search {
|
||||||
|
.icon {
|
||||||
|
mask-image: url("../img/icons/search.svg");
|
||||||
|
mask-position: center;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-size: 16px 16px;
|
||||||
|
|
||||||
|
background-color: $input-placeholder-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
&:hover {
|
||||||
|
~ .icon {
|
||||||
|
background-color: $input-hover-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
~ .icon {
|
||||||
|
background-color: $primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown.is-mobile-modal.is-expanded {
|
||||||
|
.dropdown-trigger {
|
||||||
|
.control {
|
||||||
|
.input {
|
||||||
|
&::after {
|
||||||
|
border: 1px solid #393939;
|
||||||
|
border-radius: 1px;
|
||||||
|
border-right: 0;
|
||||||
|
border-top: 0;
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
margin-top: -0.5em;
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
transform-origin: center;
|
||||||
|
height: .625em;
|
||||||
|
width: .625em;
|
||||||
|
right: 1.125em;
|
||||||
|
transition: border-color .15s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
&::after {
|
||||||
|
border-color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
&::after {
|
||||||
|
border-color: $primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-loading {
|
||||||
|
.input {
|
||||||
|
&::after {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
height: 1.14rem;
|
||||||
|
width: 1.14rem;
|
||||||
|
right: .86rem;
|
||||||
|
top: .86rem;
|
||||||
|
border-radius: 1.14rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
@include touch {
|
||||||
|
max-width: 460px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .dropdown-content {
|
||||||
|
overflow: hidden;
|
||||||
|
margin: 1px;
|
||||||
|
|
||||||
|
> .dropdown-item {
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 0.675rem 1.25rem;
|
||||||
|
transition: color .15s ease-in-out, background-color .15s ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
.dropdown-trigger {
|
||||||
|
.control {
|
||||||
|
.input {
|
||||||
|
border-color: $primary;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-color: $primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-top-right {
|
||||||
|
.dropdown-menu {
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
&-previous, &-next, &-link {
|
||||||
|
background-color: rgba($primary, .104);
|
||||||
|
font-weight: $weight-bold;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
opacity: .5;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba($primary, .104);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-previous, &-next {
|
||||||
|
.icon {
|
||||||
|
width: 9px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: $primary
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.icon {
|
||||||
|
background-color: $primary-invert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
&:hover {
|
||||||
|
.icon {
|
||||||
|
background-color: $primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-previous {
|
||||||
|
.icon {
|
||||||
|
mask-image: url("../img/icons/arrow-left.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-next {
|
||||||
|
.icon {
|
||||||
|
mask-image: url("../img/icons/arrow-right.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -129,6 +129,36 @@ $dropdown-background-color: $modal-background-background-color;
|
|||||||
$widescreen-enabled: false;
|
$widescreen-enabled: false;
|
||||||
$fullhd-enabled: false;
|
$fullhd-enabled: false;
|
||||||
|
|
||||||
|
$table-background-color: transparent;
|
||||||
|
$table-color: $white;
|
||||||
|
$table-head-cell-color: $white;
|
||||||
|
$table-head-cell-border-width: 0 0 4px;
|
||||||
|
$table-cell-border: 1px solid $primary;
|
||||||
|
$table-striped-row-even-background-color: rgba($primary, .104);
|
||||||
|
$table-row-hover-background-color: rgba($primary, .154);
|
||||||
|
$table-striped-row-even-hover-background-color: rgba($primary, .154);
|
||||||
|
$table-cell-padding: 1.5em 0.75em;
|
||||||
|
|
||||||
|
$pagination-color: $primary;
|
||||||
|
$pagination-border-color: $primary;
|
||||||
|
|
||||||
|
$pagination-hover-color: $primary-invert;
|
||||||
|
$pagination-hover-border-color: $primary;
|
||||||
|
|
||||||
|
$pagination-focus-color: $pagination-hover-color;
|
||||||
|
$pagination-focus-border-color: $pagination-hover-border-color;
|
||||||
|
|
||||||
|
$pagination-active-color: $pagination-hover-color;
|
||||||
|
$pagination-active-border-color: $pagination-hover-border-color;
|
||||||
|
|
||||||
|
$pagination-disabled-color: $primary;
|
||||||
|
$pagination-disabled-background-color: rgba($primary, .104);
|
||||||
|
$pagination-disabled-border-color: $primary;
|
||||||
|
|
||||||
|
$pagination-current-color: $primary-invert;
|
||||||
|
$pagination-current-background-color: $primary;
|
||||||
|
$pagination-current-border-color: $primary;
|
||||||
|
|
||||||
.columns {
|
.columns {
|
||||||
@include from(576px) {
|
@include from(576px) {
|
||||||
&.is-small {
|
&.is-small {
|
||||||
|
9
components/icons/Link.vue
Normal file
9
components/icons/Link.vue
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18">
|
||||||
|
<path
|
||||||
|
fill="#94FEBF"
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M17 18H1a1 1 0 0 1-1-1v-4a1 1 0 0 1 2 0v3h14v-3a1 1 0 0 1 2 0v4a1 1 0 0 1-1 1zm-7.134-6.332a1.08 1.08 0 0 1-.78.315C9.056 11.985 9.03 12 9 12c-.03 0-.056-.015-.086-.017a1.08 1.08 0 0 1-.78-.315L4.298 7.833a1.086 1.086 0 0 1 1.534-1.535L8 8.466V1a1 1 0 0 1 2 0v7.466l2.167-2.168a1.087 1.087 0 0 1 1.535 0 1.087 1.087 0 0 1 0 1.535l-3.836 3.835z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
280
pages/index.vue
280
pages/index.vue
@ -1,159 +1,167 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ceremony">
|
<div class="ceremony">
|
||||||
<div class="title is-size-1 is-spaced">
|
<h1 class="title is-size-1 is-spaced">Lorem <span>Ipsum Dolor</span></h1>
|
||||||
Hello, <span>@{{ user.handle }}</span>
|
<p class="p is-size-5">
|
||||||
</div>
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
|
||||||
<div class="subtitle">Lorem ipsum dolor sit amet, consectetur?</div>
|
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
|
||||||
<p class="p">
|
laboris nisi ut aliquip ex ea commodo consequat.
|
||||||
If you don’t trust binaries, we encorage you to follow this <a href="">instruction</a> to
|
|
||||||
contribute by compiling from source code. It is very easy!
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div class="column is-one-third">
|
|
||||||
<div class="box">
|
|
||||||
<div class="title is-5">Lorem ipsum</div>
|
|
||||||
<Cloak />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column is-one-third">
|
|
||||||
<div :class="{ 'is-hovered': isLoggedIn }" class="box">
|
|
||||||
<div class="title is-5">Lorem ipsum</div>
|
|
||||||
<div v-if="isLoggedIn" class="fields">
|
|
||||||
<b-field label="Name">
|
|
||||||
<b-input v-model="user.name"></b-input>
|
|
||||||
</b-field>
|
|
||||||
<b-field label="Company">
|
|
||||||
<b-input v-model="user.company"></b-input>
|
|
||||||
</b-field>
|
|
||||||
</div>
|
|
||||||
<div v-else class="buttons">
|
|
||||||
<b-button @click="logIn" type="is-primary" outlined expanded>
|
|
||||||
Sign In
|
|
||||||
</b-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-show="status.msg !== ''" class="status">
|
|
||||||
<div :class="status.type" class="status-message">{{ status.msg }}</div>
|
|
||||||
<div v-show="status.type === ''" class="status-spinner"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="buttons is-centered">
|
<div class="buttons is-centered">
|
||||||
<b-button
|
<b-button type="is-primary" outlined tag="router-link" to="/make-contribution">
|
||||||
v-if="!isContributeBtnDisabled"
|
|
||||||
@click="makeContribution"
|
|
||||||
type="is-primary"
|
|
||||||
outlined
|
|
||||||
>
|
|
||||||
Make the contribution
|
Make the contribution
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button
|
|
||||||
v-if="isContributeBtnDisabled && status.type === 'is-success'"
|
|
||||||
type="is-primary"
|
|
||||||
tag="a"
|
|
||||||
href="https://twitter.com/intent/tweet?text=Hello%20world"
|
|
||||||
target="_blank"
|
|
||||||
outlined
|
|
||||||
>
|
|
||||||
Tweet about your contribution
|
|
||||||
</b-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="currently">Currently there are <span>8999</span> contributions</div>
|
||||||
|
|
||||||
|
<b-table
|
||||||
|
:data="filteredContributions"
|
||||||
|
:hoverable="true"
|
||||||
|
:mobile-cards="false"
|
||||||
|
:per-page="rowsPerPage"
|
||||||
|
paginated
|
||||||
|
pagination-position="both"
|
||||||
|
>
|
||||||
|
<template slot-scope="props">
|
||||||
|
<b-table-column field="id" label="#" width="40" numeric>
|
||||||
|
{{ props.row.id }}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column label="Account">
|
||||||
|
<a :href="`#${props.row.account}`" target="_blank">{{ props.row.account }}</a>
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="name" label="Name">
|
||||||
|
{{ props.row.name }}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column field="company" label="Company">
|
||||||
|
{{ props.row.company }}
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column label="Attestation">
|
||||||
|
<a :href="props.row.attestation" target="_blank">{{ props.row.account }}</a>
|
||||||
|
</b-table-column>
|
||||||
|
|
||||||
|
<b-table-column>
|
||||||
|
<a :href="props.row.contribution" class="button is-icon">
|
||||||
|
<Link />
|
||||||
|
</a>
|
||||||
|
</b-table-column>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="empty">
|
||||||
|
<section class="section">
|
||||||
|
<div class="content has-text-centered">
|
||||||
|
<p>
|
||||||
|
<span class="icon icon-emoticon-sad icon-48px"></span>
|
||||||
|
</p>
|
||||||
|
<p>Nothing here.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="top-left">
|
||||||
|
<b-field class="table-search">
|
||||||
|
<b-input
|
||||||
|
v-model="contributionSearch"
|
||||||
|
placeholder="Search..."
|
||||||
|
type="search"
|
||||||
|
icon="magnify"
|
||||||
|
></b-input>
|
||||||
|
</b-field>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template slot="bottom-left">
|
||||||
|
<b-field horizontal label="Show">
|
||||||
|
<b-dropdown v-model="rowsPerPage" expanded aria-role="list" position="is-top-right">
|
||||||
|
<div slot="trigger" class="control">
|
||||||
|
<div class="input">
|
||||||
|
<span>{{ rowsPerPage }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<b-dropdown-item
|
||||||
|
v-for="(rows, index) in [10, 15, 20, 50]"
|
||||||
|
:key="index"
|
||||||
|
:value="rows"
|
||||||
|
aria-role="listitem"
|
||||||
|
>
|
||||||
|
{{ rows }}
|
||||||
|
</b-dropdown-item>
|
||||||
|
</b-dropdown>
|
||||||
|
</b-field>
|
||||||
|
</template>
|
||||||
|
</b-table>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/* eslint-disable no-console */
|
import Link from '@/components/icons/Link'
|
||||||
import Cloak from '@/components/Cloak'
|
|
||||||
const timeout = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Cloak
|
Link
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isContributeBtnDisabled: false,
|
contributions: [
|
||||||
status: {
|
{
|
||||||
type: '',
|
id: 1,
|
||||||
msg: ''
|
account: '@VitalikButerin',
|
||||||
},
|
name: 'Vitalik Buterin',
|
||||||
user: { name: '', handle: 'Anonymous', company: '' }
|
company: 'Ethereum',
|
||||||
|
attestation: 'https://twitter.com/VitalikButerin/status/1220158987456237568',
|
||||||
|
contribution: '#'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
account: '@Chims1974',
|
||||||
|
name: 'Rickey Kline',
|
||||||
|
company: 'Big Wheel',
|
||||||
|
attestation: '#',
|
||||||
|
contribution: '#'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
account: '@Diguest',
|
||||||
|
name: 'Ryan Obrien',
|
||||||
|
company: 'Brilliant Home',
|
||||||
|
attestation: '#',
|
||||||
|
contribution: '#'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
account: '@Mathervenrat',
|
||||||
|
name: 'William Hartwig',
|
||||||
|
company: 'New World',
|
||||||
|
attestation: '#',
|
||||||
|
contribution: '#'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
account: '@Hichercy',
|
||||||
|
name: 'Wayne Biggins',
|
||||||
|
company: 'Balanced Fortune',
|
||||||
|
attestation: '#',
|
||||||
|
contribution: '#'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
account: '',
|
||||||
|
name: 'Anonymous',
|
||||||
|
company: '',
|
||||||
|
attestation: '',
|
||||||
|
contribution: '#'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
rowsPerPage: 10,
|
||||||
|
contributionSearch: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isLoggedIn() {
|
filteredContributions() {
|
||||||
return !!this.user.name && this.user.name !== 'Anonymous'
|
return this.contributions.filter((contribution) => {
|
||||||
}
|
return contribution.name.toLowerCase().includes(this.contributionSearch.toLowerCase())
|
||||||
},
|
})
|
||||||
async mounted() {
|
|
||||||
try {
|
|
||||||
const data = await this.$axios.$get('/api/user_data')
|
|
||||||
console.log('data', data)
|
|
||||||
if (data.name !== 'Anonymous') {
|
|
||||||
this.user.handle = data.handle
|
|
||||||
this.user.name = data.name
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('user_data fail', e)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async makeContribution({ retry = 0 } = {}) {
|
|
||||||
try {
|
|
||||||
this.isContributeBtnDisabled = true
|
|
||||||
|
|
||||||
this.status.msg = 'Downloading last contribution'
|
|
||||||
this.status.type = ''
|
|
||||||
let data = await fetch('api/challenge')
|
|
||||||
data = new Uint8Array(await data.arrayBuffer())
|
|
||||||
|
|
||||||
this.status.msg = 'Generating random contribution'
|
|
||||||
await timeout(100) // allow UI to update before freezing in wasm
|
|
||||||
console.log('Source params', data)
|
|
||||||
const contribute = await this.$contribute()
|
|
||||||
const result = contribute(data)
|
|
||||||
console.log('Updated params', result)
|
|
||||||
|
|
||||||
this.status.msg = 'Uploading and verifying your contribution'
|
|
||||||
console.log('this.user.name', this.user)
|
|
||||||
const formData = new FormData()
|
|
||||||
formData.append('response', new Blob([result], { type: 'application/octet-stream' }))
|
|
||||||
formData.append('name', this.user.name)
|
|
||||||
formData.append('company', this.user.company)
|
|
||||||
const resp = await fetch('api/response', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData
|
|
||||||
})
|
|
||||||
|
|
||||||
if (resp.ok) {
|
|
||||||
this.status.msg = 'Your contribution is verified and recorded. THX BYE.'
|
|
||||||
this.status.type = 'is-success'
|
|
||||||
} else if (resp.status === 422) {
|
|
||||||
if (retry < 3) {
|
|
||||||
console.log(`Looks like someone else uploaded contribution ahead of us, retrying`)
|
|
||||||
await this.makeContribution({ retry: retry++ })
|
|
||||||
} else {
|
|
||||||
this.status.msg = `Failed to upload your contribution after ${retry} attempts`
|
|
||||||
this.status.type = 'is-danger'
|
|
||||||
this.isContributeBtnDisabled = false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.status.msg = 'Error uploading your contribution'
|
|
||||||
this.status.type = 'is-danger'
|
|
||||||
this.isContributeBtnDisabled = false
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e.message)
|
|
||||||
this.status.msg = e.message
|
|
||||||
this.status.type = 'is-danger'
|
|
||||||
this.isContributeBtnDisabled = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
logIn() {
|
|
||||||
window.location.replace('/api/connect')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
160
pages/make-contribution.vue
Normal file
160
pages/make-contribution.vue
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ceremony">
|
||||||
|
<h1 class="title is-size-1 is-spaced">
|
||||||
|
Hello, <span>@{{ user.handle }}</span>
|
||||||
|
</h1>
|
||||||
|
<h2 class="subtitle">Lorem ipsum dolor sit amet, consectetur?</h2>
|
||||||
|
<p class="p">
|
||||||
|
If you don’t trust binaries, we encorage you to follow this <a href="">instruction</a> to
|
||||||
|
contribute by compiling from source code. It is very easy!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="columns is-centered">
|
||||||
|
<div class="column is-one-third">
|
||||||
|
<div class="box">
|
||||||
|
<div class="title is-5">Lorem ipsum</div>
|
||||||
|
<Cloak />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column is-one-third">
|
||||||
|
<div :class="{ 'is-hovered': isLoggedIn }" class="box">
|
||||||
|
<div class="title is-5">Lorem ipsum</div>
|
||||||
|
<div v-if="isLoggedIn" class="fields">
|
||||||
|
<b-field label="Name">
|
||||||
|
<b-input v-model="user.name"></b-input>
|
||||||
|
</b-field>
|
||||||
|
<b-field label="Company">
|
||||||
|
<b-input v-model="user.company"></b-input>
|
||||||
|
</b-field>
|
||||||
|
</div>
|
||||||
|
<div v-else class="buttons">
|
||||||
|
<b-button @click="logIn" type="is-primary" outlined expanded>
|
||||||
|
Sign In
|
||||||
|
</b-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-show="status.msg !== ''" class="status">
|
||||||
|
<div :class="status.type" class="status-message">{{ status.msg }}</div>
|
||||||
|
<div v-show="status.type === ''" class="status-spinner"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttons is-centered">
|
||||||
|
<b-button
|
||||||
|
v-if="!isContributeBtnDisabled"
|
||||||
|
@click="makeContribution"
|
||||||
|
type="is-primary"
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
Make the contribution
|
||||||
|
</b-button>
|
||||||
|
<b-button
|
||||||
|
v-if="isContributeBtnDisabled && status.type === 'is-success'"
|
||||||
|
type="is-primary"
|
||||||
|
tag="a"
|
||||||
|
href="https://twitter.com/intent/tweet?text=Hello%20world"
|
||||||
|
target="_blank"
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
Tweet about your contribution
|
||||||
|
</b-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
import Cloak from '@/components/Cloak'
|
||||||
|
const timeout = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Cloak
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isContributeBtnDisabled: false,
|
||||||
|
status: {
|
||||||
|
type: '',
|
||||||
|
msg: ''
|
||||||
|
},
|
||||||
|
user: { name: '', handle: 'Anonymous', company: '' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isLoggedIn() {
|
||||||
|
return !!this.user.name && this.user.name !== 'Anonymous'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async mounted() {
|
||||||
|
try {
|
||||||
|
const data = await this.$axios.$get('/api/user_data')
|
||||||
|
console.log('data', data)
|
||||||
|
if (data.name !== 'Anonymous') {
|
||||||
|
this.user.handle = data.handle
|
||||||
|
this.user.name = data.name
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('user_data fail', e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async makeContribution({ retry = 0 } = {}) {
|
||||||
|
try {
|
||||||
|
this.isContributeBtnDisabled = true
|
||||||
|
|
||||||
|
this.status.msg = 'Downloading last contribution'
|
||||||
|
this.status.type = ''
|
||||||
|
let data = await fetch('api/challenge')
|
||||||
|
data = new Uint8Array(await data.arrayBuffer())
|
||||||
|
|
||||||
|
this.status.msg = 'Generating random contribution'
|
||||||
|
await timeout(100) // allow UI to update before freezing in wasm
|
||||||
|
console.log('Source params', data)
|
||||||
|
const contribute = await this.$contribute()
|
||||||
|
const result = contribute(data)
|
||||||
|
console.log('Updated params', result)
|
||||||
|
|
||||||
|
this.status.msg = 'Uploading and verifying your contribution'
|
||||||
|
console.log('this.user.name', this.user)
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('response', new Blob([result], { type: 'application/octet-stream' }))
|
||||||
|
formData.append('name', this.user.name)
|
||||||
|
formData.append('company', this.user.company)
|
||||||
|
const resp = await fetch('api/response', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
|
||||||
|
if (resp.ok) {
|
||||||
|
this.status.msg = 'Your contribution is verified and recorded. THX BYE.'
|
||||||
|
this.status.type = 'is-success'
|
||||||
|
} else if (resp.status === 422) {
|
||||||
|
if (retry < 3) {
|
||||||
|
console.log(`Looks like someone else uploaded contribution ahead of us, retrying`)
|
||||||
|
await this.makeContribution({ retry: retry++ })
|
||||||
|
} else {
|
||||||
|
this.status.msg = `Failed to upload your contribution after ${retry} attempts`
|
||||||
|
this.status.type = 'is-danger'
|
||||||
|
this.isContributeBtnDisabled = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.status.msg = 'Error uploading your contribution'
|
||||||
|
this.status.type = 'is-danger'
|
||||||
|
this.isContributeBtnDisabled = false
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e.message)
|
||||||
|
this.status.msg = e.message
|
||||||
|
this.status.type = 'is-danger'
|
||||||
|
this.isContributeBtnDisabled = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
logIn() {
|
||||||
|
window.location.replace('/api/connect')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user