@visualizevalue/mint-app-base 0.0.7 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +1 -1
- package/app/assets/styles/animation.css +1 -9
- package/app/assets/styles/base.css +3 -12
- package/app/assets/styles/forms.css +18 -54
- package/app/assets/styles/index.css +24 -6
- package/app/assets/styles/normalize.css +8 -3
- package/app/assets/styles/prose.css +2 -128
- package/app/assets/styles/variables/animations.css +8 -0
- package/app/assets/styles/variables/borders.css +13 -0
- package/app/assets/styles/variables/colors.css +48 -0
- package/app/assets/styles/{theme.css → variables/components.css} +8 -2
- package/app/assets/styles/variables/effects.css +11 -0
- package/app/assets/styles/variables/fonts.css +26 -0
- package/app/assets/styles/variables/layout.css +9 -0
- package/app/assets/styles/variables/sizes.css +23 -0
- package/app/assets/styles/variables/ui.css +17 -0
- package/app/assets/styles/variables.css +16 -192
- package/app/assets/styles/web3-modals.css +2 -7
- package/app/components/Account.client.vue +1 -1
- package/app/components/Actions.vue +2 -3
- package/app/components/AppHeader.vue +2 -25
- package/app/components/Breadcrumbs.vue +1 -1
- package/app/components/Button/AddCollection.vue +10 -0
- package/app/components/Button/EditProfile.vue +10 -0
- package/app/components/Button/Profile/Discord.vue +10 -0
- package/app/components/Button/Profile/Email.vue +10 -0
- package/app/components/Button/Profile/Github.vue +11 -0
- package/app/components/Button/Profile/Twitter.vue +10 -0
- package/app/components/Button/Profile/Website.vue +10 -0
- package/app/components/Button.vue +17 -36
- package/app/components/CheckSpinner.vue +0 -18
- package/app/components/Collection/Intro.vue +9 -6
- package/app/components/Collection/OverviewCard.vue +11 -5
- package/app/components/Collection/Withdraw.client.vue +2 -1
- package/app/components/DialogFrame.vue +4 -7
- package/app/components/Form/Group.vue +19 -4
- package/app/components/Form/SelectFile.vue +1 -1
- package/app/components/Icon.vue +21 -17
- package/app/components/Image.client.vue +0 -4
- package/app/components/Loading.vue +2 -38
- package/app/components/MintGasPricePopover.client.vue +2 -2
- package/app/components/MintToken.vue +1 -1
- package/app/components/Modal.vue +3 -2
- package/app/components/Popover.client.vue +3 -23
- package/app/components/Profile/Header.client.vue +6 -35
- package/app/components/Token/Detail.client.vue +19 -10
- package/app/components/Token/MintTimeline.client.vue +14 -43
- package/app/components/Token/MintTimelineItem.vue +50 -13
- package/app/components/Token/OverviewCard.vue +10 -17
- package/app/components/TransactionFlow.vue +4 -10
- package/app/layouts/default.vue +2 -14
- package/app/pages/[id]/[collection]/[tokenId]/index.vue +1 -1
- package/app/pages/[id]/[collection]/index.vue +1 -1
- package/app/pages/[id]/[collection]/mint.vue +4 -4
- package/app/pages/[id]/create.vue +49 -49
- package/app/pages/[id]/index.vue +1 -6
- package/app/pages/profile/[address]/index.vue +1 -4
- package/app/plugins/2.wagmi.ts +2 -2
- package/package.json +2 -1
- package/app/assets/styles/scroll.css +0 -13
- package/app/assets/styles/text.css +0 -14
- package/app/assets/styles/utils.css +0 -24
- package/app/components/Avatar.vue +0 -61
- package/app/components/CountDown.vue +0 -153
- package/app/components/IconLink.vue +0 -29
- package/app/components/Navbar.client.vue +0 -86
- package/app/components/QueryDialog.vue +0 -38
- package/app/components/ToggleDarkMode.client.vue +0 -58
- /package/app/components/{Visual/ImagePreview.vue → ImagePreview.vue} +0 -0
|
@@ -18,6 +18,7 @@ fieldset {
|
|
|
18
18
|
max-width: -webkit-fill-available;
|
|
19
19
|
display: flex;
|
|
20
20
|
flex-wrap: wrap;
|
|
21
|
+
position: relative;
|
|
21
22
|
|
|
22
23
|
> * {
|
|
23
24
|
width: 100cqw;
|
|
@@ -49,20 +50,34 @@ fieldset {
|
|
|
49
50
|
|
|
50
51
|
:deep(> .form-item),
|
|
51
52
|
:deep(> .button) {
|
|
53
|
+
z-index: 1;
|
|
54
|
+
|
|
55
|
+
&:--highlight,
|
|
56
|
+
&:has(.input:hover),
|
|
57
|
+
&:has(.input:focus) {
|
|
58
|
+
z-index: 2;
|
|
59
|
+
}
|
|
60
|
+
|
|
52
61
|
+ .form-item,
|
|
53
62
|
+ .button {
|
|
54
|
-
|
|
63
|
+
margin-top: calc(-1 * var(--border-width));
|
|
55
64
|
|
|
65
|
+
&:--highlight,
|
|
66
|
+
&:has(.input:hover),
|
|
56
67
|
&:has(.input:focus) {
|
|
57
|
-
border-top-color: var(--border-color-
|
|
68
|
+
border-top-color: var(--button-border-color-highlight);
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
@container (min-width: 30rem) {
|
|
61
72
|
border-top-color: var(--border-color);
|
|
62
|
-
|
|
73
|
+
margin-top: 0;
|
|
74
|
+
margin-left: calc(-1 * var(--border-width));
|
|
63
75
|
|
|
76
|
+
&:--highlight,
|
|
77
|
+
&:has(.input:hover),
|
|
64
78
|
&:has(.input:focus) {
|
|
65
|
-
border-
|
|
79
|
+
border-top-color: var(--button-border-color-highlight);
|
|
80
|
+
border-left-color: var(--button-border-color-highlight);
|
|
66
81
|
}
|
|
67
82
|
}
|
|
68
83
|
}
|
package/app/components/Icon.vue
CHANGED
|
@@ -1,37 +1,41 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<i v-if="ICONS[type]" class="icon">
|
|
3
|
-
|
|
3
|
+
{{ symbol }}
|
|
4
4
|
</i>
|
|
5
|
-
<FeatherIcon v-else :type="type" class="icon" />
|
|
6
5
|
</template>
|
|
7
6
|
|
|
8
7
|
<script setup>
|
|
9
|
-
import FeatherIcon from 'vue-feather'
|
|
10
|
-
|
|
11
8
|
const props = defineProps({
|
|
12
9
|
type: String,
|
|
13
10
|
})
|
|
14
11
|
|
|
15
12
|
const ICONS = {
|
|
16
|
-
'
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
home: '🜂',
|
|
14
|
+
trash: '✕',
|
|
15
|
+
times: '✕',
|
|
16
|
+
close: '✕',
|
|
17
|
+
folder: '✏',
|
|
18
|
+
edit: '✏',
|
|
19
|
+
check: '✓',
|
|
20
|
+
add: '+',
|
|
21
|
+
image: '+',
|
|
22
|
+
link: '↗︎',
|
|
23
|
+
user: '☻',
|
|
24
|
+
loader: 'ⴵ',
|
|
25
|
+
'chevron-up': '↑',
|
|
26
|
+
'chevron-down': '↓',
|
|
27
|
+
'chevron-right': '→',
|
|
28
|
+
withdraw: 'Ξ',
|
|
19
29
|
}
|
|
30
|
+
|
|
31
|
+
const symbol = computed(() => ICONS[props.type])
|
|
20
32
|
</script>
|
|
21
33
|
|
|
22
34
|
<style scoped>
|
|
23
35
|
.icon {
|
|
24
|
-
display: inline-
|
|
36
|
+
display: inline-flex;
|
|
25
37
|
width: var(--size-4);
|
|
26
38
|
height: var(--size-4);
|
|
27
|
-
|
|
28
|
-
:deep(svg) {
|
|
29
|
-
width: 100%;
|
|
30
|
-
height: 100%;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
&.spin {
|
|
34
|
-
animation: spin 5s infinite linear;
|
|
35
|
-
}
|
|
39
|
+
align-items: center;
|
|
36
40
|
}
|
|
37
41
|
</style>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="loader">
|
|
3
|
-
<span class="spinner"></span>
|
|
4
3
|
<span v-if="txt" class="text">{{ txt }}</span>
|
|
5
4
|
</div>
|
|
6
5
|
</template>
|
|
@@ -26,8 +25,8 @@ const { txt } = defineProps({
|
|
|
26
25
|
.text {
|
|
27
26
|
text-transform: var(--text-transform-ui);
|
|
28
27
|
color: var(--muted);
|
|
29
|
-
font-family: var(--font-family
|
|
30
|
-
font-weight: var(--font-weight
|
|
28
|
+
font-family: var(--ui-font-family);
|
|
29
|
+
font-weight: var(--ui-font-weight);
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
&:not(.inline) {
|
|
@@ -40,40 +39,5 @@ const { txt } = defineProps({
|
|
|
40
39
|
gap: var(--size-1);
|
|
41
40
|
margin-left: var(--size-1);
|
|
42
41
|
}
|
|
43
|
-
|
|
44
|
-
&.large {
|
|
45
|
-
font-size: var(--font-size-xl);
|
|
46
|
-
|
|
47
|
-
.spinner {
|
|
48
|
-
border-width: 4px;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
&.simple {
|
|
53
|
-
.text {
|
|
54
|
-
display: none;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.spinner {
|
|
59
|
-
position: relative;
|
|
60
|
-
display: inline-block;
|
|
61
|
-
width: 0.75em;
|
|
62
|
-
height: 0.75em;
|
|
63
|
-
border-radius: 50%;
|
|
64
|
-
border: 2px solid var(--gray-z-6);
|
|
65
|
-
border-right-color: var(--gray-z-3);
|
|
66
|
-
flex-shrink: 0;
|
|
67
|
-
animation: spin infinite linear 1s;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@keyframes spin {
|
|
72
|
-
0% {
|
|
73
|
-
transform: rotate(0);
|
|
74
|
-
}
|
|
75
|
-
100% {
|
|
76
|
-
transform: rotate(360deg);
|
|
77
|
-
}
|
|
78
42
|
}
|
|
79
43
|
</style>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<Popover id="about-gas">
|
|
3
3
|
<template #trigger><MintGasPrice :mint-count="2" /></template>
|
|
4
4
|
<template #content>
|
|
5
|
-
<div class="
|
|
5
|
+
<div class="prose">
|
|
6
6
|
<h1>Mint Pricing</h1>
|
|
7
7
|
<p>Artifacts are priced based on the ethereum network fees at the time of collecting.</p>
|
|
8
8
|
<p>Network fees (Gas fees) are an essential component of of securing and running decentralized blockchains.</p>
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
margin-left: auto;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
|
|
69
68
|
</style>
|
|
69
|
+
|
package/app/components/Modal.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<DialogFrame class="modal" ref="dialog">
|
|
3
|
-
<button v-if="xClose" class="close" @click="$emit('close')"><Icon type="
|
|
2
|
+
<DialogFrame class="modal" :class="class" ref="dialog">
|
|
3
|
+
<button v-if="xClose" class="close" @click="$emit('close')"><Icon type="close" /></button>
|
|
4
4
|
|
|
5
5
|
<slot />
|
|
6
6
|
</DialogFrame>
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
<script setup>
|
|
10
10
|
const props = defineProps({
|
|
11
11
|
open: Boolean,
|
|
12
|
+
class: String,
|
|
12
13
|
xClose: {
|
|
13
14
|
type: Boolean,
|
|
14
15
|
default: true,
|
|
@@ -31,12 +31,12 @@ const trigger = ref()
|
|
|
31
31
|
const popover = ref()
|
|
32
32
|
|
|
33
33
|
const { width: windowWidth } = useWindowSize()
|
|
34
|
-
const { width: dialogWidth } = useElementSize(popover,
|
|
34
|
+
const { width: dialogWidth } = useElementSize(popover, undefined, { box: 'border-box' })
|
|
35
35
|
const { x: targetX, y: targetY, width: targetWidth, height: targetHeight } = useElementBounding(trigger)
|
|
36
36
|
const targetCenterX = computed(() => targetX.value + targetWidth.value / 2)
|
|
37
37
|
const adjustmentX = computed(() => {
|
|
38
38
|
const popoverLeft = targetCenterX.value - (dialogWidth.value / 2)
|
|
39
|
-
const overflow = parseInt(windowWidth.value - (popoverLeft + dialogWidth.value) - 29)
|
|
39
|
+
const overflow = parseInt(`${windowWidth.value - (popoverLeft + dialogWidth.value) - 29}`)
|
|
40
40
|
return overflow < 0 ? overflow : 0
|
|
41
41
|
})
|
|
42
42
|
|
|
@@ -73,7 +73,7 @@ const popoverArrowPosition = computed(() => {
|
|
|
73
73
|
|
|
74
74
|
&:popover-open {
|
|
75
75
|
opacity: 1;
|
|
76
|
-
transform: translateY(var(--spacer));
|
|
76
|
+
transform: translateY(var(--spacer-sm));
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
.arrow {
|
|
@@ -96,24 +96,4 @@ const popoverArrowPosition = computed(() => {
|
|
|
96
96
|
transform: translateY(var(--spacer-lg));
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
|
-
|
|
100
|
-
/* BACKDROP */
|
|
101
|
-
/* [popover]::backdrop {
|
|
102
|
-
background-color: var(--background-0);
|
|
103
|
-
transition:
|
|
104
|
-
display 0.7s allow-discrete,
|
|
105
|
-
overlay 0.7s allow-discrete,
|
|
106
|
-
background-color 0.7s;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
[popover]:popover-open::backdrop {
|
|
110
|
-
background-color: var(--background-semi);
|
|
111
|
-
backdrop-filter: var(--blur);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
@starting-style {
|
|
115
|
-
[popover]:popover-open::backdrop {
|
|
116
|
-
background-color: var(--background-0);
|
|
117
|
-
}
|
|
118
|
-
} */
|
|
119
99
|
</style>
|
|
@@ -10,24 +10,12 @@
|
|
|
10
10
|
</h1>
|
|
11
11
|
<p v-if="artist?.description">{{ artist.description }}</p>
|
|
12
12
|
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<Icon type="mail" />
|
|
20
|
-
<span>{{ artist.email }}</span>
|
|
21
|
-
</Button>
|
|
22
|
-
<Button v-if="artist.twitter" :to="`https://x.com/${artist.twitter}`" class="small">
|
|
23
|
-
<Icon type="x.com" />
|
|
24
|
-
<span>{{ artist.twitter }}</span>
|
|
25
|
-
</Button>
|
|
26
|
-
<Button v-if="artist.github" :to="`https://github.com/${artist.github}`" class="small">
|
|
27
|
-
<Icon type="github" />
|
|
28
|
-
<span>{{ artist.github }}</span>
|
|
29
|
-
</Button>
|
|
30
|
-
</ul>
|
|
13
|
+
<Actions v-if="hasTags">
|
|
14
|
+
<ButtonProfileWebsite :profile="artist" />
|
|
15
|
+
<ButtonProfileEmail :profile="artist" />
|
|
16
|
+
<ButtonProfileTwitter :profile="artist" />
|
|
17
|
+
<ButtonProfileGithub :profile="artist" />
|
|
18
|
+
</Actions>
|
|
31
19
|
</header>
|
|
32
20
|
</template>
|
|
33
21
|
|
|
@@ -56,20 +44,15 @@ const hasTags = computed(() => artist.value.url ||
|
|
|
56
44
|
header {
|
|
57
45
|
display: flex;
|
|
58
46
|
flex-direction: column;
|
|
59
|
-
justify-content: center;
|
|
60
|
-
align-items: center;
|
|
61
47
|
gap: var(--spacer);
|
|
62
48
|
|
|
63
49
|
img {
|
|
64
50
|
width: var(--size-9);
|
|
65
51
|
height: var(--size-9);
|
|
66
|
-
border-radius: 50%;
|
|
67
|
-
border: var(--border);
|
|
68
52
|
}
|
|
69
53
|
|
|
70
54
|
h1 {
|
|
71
55
|
cursor: pointer;
|
|
72
|
-
text-align: center;
|
|
73
56
|
|
|
74
57
|
> * {
|
|
75
58
|
display: block;
|
|
@@ -80,17 +63,5 @@ header {
|
|
|
80
63
|
font-size: var(--font-xs);
|
|
81
64
|
}
|
|
82
65
|
}
|
|
83
|
-
|
|
84
|
-
p {
|
|
85
|
-
color: var(--muted);
|
|
86
|
-
text-align: center;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
ul {
|
|
90
|
-
display: flex;
|
|
91
|
-
flex-wrap: wrap;
|
|
92
|
-
gap: var(--spacer-sm);
|
|
93
|
-
justify-content: center;
|
|
94
|
-
}
|
|
95
66
|
}
|
|
96
67
|
</style>
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
>
|
|
23
23
|
<section class="details">
|
|
24
24
|
<header class="title">
|
|
25
|
-
<h1>{{ token.name }} <
|
|
26
|
-
<p v-if="token.description"
|
|
25
|
+
<h1>{{ token.name }} <small>#{{ token.tokenId }}</small></h1>
|
|
26
|
+
<p v-if="token.description">
|
|
27
27
|
<ExpandableText :text="token.description" :length="95" expand-text="Read More" />
|
|
28
28
|
</p>
|
|
29
|
-
<p class="
|
|
29
|
+
<p v-if="collection" class="artist">
|
|
30
30
|
By <NuxtLink :to="{ name: 'id', params: { id: collection.owner } }">{{ store.displayName(collection.owner) }}</NuxtLink>
|
|
31
31
|
</p>
|
|
32
32
|
</header>
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
|
|
48
48
|
<div class="mint-status">
|
|
49
49
|
<p v-if="mintOpen">{{ blocksRemaining }} blocks remaining</p>
|
|
50
|
-
<p v-else-if="currentBlock"
|
|
51
|
-
<p
|
|
50
|
+
<p v-else-if="currentBlock">Closed at block {{ token.untilBlock }}</p>
|
|
51
|
+
<p v-if="ownedBalance">You own {{ ownedBalance }} {{ pluralize('token', Number(ownedBalance)) }}</p>
|
|
52
52
|
</div>
|
|
53
53
|
|
|
54
54
|
<TokenMintTimeline :token="token" :collection="collection" class="network-mints" />
|
|
@@ -79,12 +79,17 @@ const ownedBalance = computed(() => collection.value && store.tokenBalance(colle
|
|
|
79
79
|
display: grid;
|
|
80
80
|
grid-auto-rows: min-content;
|
|
81
81
|
padding: 0 !important;
|
|
82
|
+
border-top: var(--border);
|
|
82
83
|
|
|
83
84
|
@media (--md) {
|
|
84
85
|
height: calc(100dvh - var(--navbar-height));
|
|
85
|
-
grid-template-columns:
|
|
86
|
+
grid-template-columns: 50% 1fr;
|
|
86
87
|
grid-auto-rows: auto;
|
|
87
88
|
}
|
|
89
|
+
|
|
90
|
+
@media (--lg) {
|
|
91
|
+
grid-template-columns: 60% 1fr;
|
|
92
|
+
}
|
|
88
93
|
}
|
|
89
94
|
|
|
90
95
|
.artifact {
|
|
@@ -92,12 +97,11 @@ const ownedBalance = computed(() => collection.value && store.tokenBalance(colle
|
|
|
92
97
|
--padding-top: 0;
|
|
93
98
|
--padding-bottom: 0;
|
|
94
99
|
--width: 100cqw;
|
|
95
|
-
/* --height: calc(100cqh - var(--padding-top) - var(--padding-bottom)); */
|
|
96
100
|
--height: 100%;
|
|
97
101
|
--dimension: min(100cqw, 100cqh);
|
|
98
102
|
|
|
99
103
|
@media (--md) {
|
|
100
|
-
--width:
|
|
104
|
+
--width: 50cqw;
|
|
101
105
|
--height: calc(100cqh - var(--navbar-height));
|
|
102
106
|
--padding-top: var(--spacer-lg);
|
|
103
107
|
--padding-x: var(--spacer-lg);
|
|
@@ -105,12 +109,13 @@ const ownedBalance = computed(() => collection.value && store.tokenBalance(colle
|
|
|
105
109
|
--padding-bottom: var(--spacer-lg);
|
|
106
110
|
|
|
107
111
|
--dimension: min(
|
|
108
|
-
calc(
|
|
112
|
+
calc(var(--width) - var(--padding-x)*2),
|
|
109
113
|
calc(100cqh - var(--padding-top) - var(--padding-bottom))
|
|
110
114
|
);
|
|
111
115
|
}
|
|
112
116
|
|
|
113
117
|
@media (--lg) {
|
|
118
|
+
--width: 60cqw;
|
|
114
119
|
--padding-top: var(--spacer-xl);
|
|
115
120
|
--padding-x: var(--spacer-xl);
|
|
116
121
|
--padding-bottom: calc(var(--spacer-xl) + var(--spacer));
|
|
@@ -159,11 +164,15 @@ const ownedBalance = computed(() => collection.value && store.tokenBalance(colle
|
|
|
159
164
|
z-index: 100;
|
|
160
165
|
display: grid;
|
|
161
166
|
gap: var(--spacer-sm);
|
|
162
|
-
background: var(--background
|
|
167
|
+
background: var(--card-background);
|
|
163
168
|
backdrop-filter: var(--blur);
|
|
164
169
|
|
|
165
170
|
h1 {
|
|
166
171
|
font-size: var(--font-lg);
|
|
172
|
+
|
|
173
|
+
small {
|
|
174
|
+
color: var(--muted);
|
|
175
|
+
}
|
|
167
176
|
}
|
|
168
177
|
|
|
169
178
|
@media (--md) {
|
|
@@ -1,30 +1,28 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<section>
|
|
2
|
+
<section class="token-mint-timeline">
|
|
3
3
|
<h1>Mint Timeline</h1>
|
|
4
4
|
|
|
5
|
-
<div v-if="currentBlock" class="
|
|
5
|
+
<div v-if="currentBlock" class="token-mint-timeline-items">
|
|
6
6
|
<TokenMintTimelineItem
|
|
7
7
|
v-for="mint of mints"
|
|
8
8
|
:mint="mint"
|
|
9
9
|
:key="mint.tx"
|
|
10
10
|
:block="currentBlock"
|
|
11
11
|
/>
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
<Account :address="collection.owner" />
|
|
15
|
-
</span>
|
|
12
|
+
<TokenMintTimelineItem v-if="! loading || mints.length">
|
|
13
|
+
<Account :address="collection.owner" class="account" />
|
|
16
14
|
|
|
17
|
-
<span class="
|
|
18
|
-
<span class="
|
|
15
|
+
<span class="amount">1<span>×</span></span>
|
|
16
|
+
<span class="price">Artist Mint</span>
|
|
19
17
|
|
|
20
|
-
<span class="
|
|
18
|
+
<span class="time-ago"><BlocksTimeAgo v-if="currentBlock" :blocks="currentBlock - (token.untilBlock - 7200n)" /></span>
|
|
21
19
|
|
|
22
|
-
<span class="
|
|
20
|
+
<span class="links">
|
|
23
21
|
<NuxtLink :to="`${config.public.blockExplorer}/nft/${token.collection}/${token.tokenId}`" target="_blank">
|
|
24
22
|
<Icon type="link" />
|
|
25
23
|
</NuxtLink>
|
|
26
24
|
</span>
|
|
27
|
-
</
|
|
25
|
+
</TokenMintTimelineItem>
|
|
28
26
|
</div>
|
|
29
27
|
|
|
30
28
|
<Loading v-if="loading || ! currentBlock" txt="Mint History..." />
|
|
@@ -62,9 +60,9 @@ watch(currentBlock, () => state.fetchTokenMints(token))
|
|
|
62
60
|
</script>
|
|
63
61
|
|
|
64
62
|
<style scoped>
|
|
65
|
-
|
|
66
|
-
padding-top: var(--spacer-lg)
|
|
67
|
-
padding-bottom: var(--spacer-lg)
|
|
63
|
+
.token-mint-timeline {
|
|
64
|
+
padding-top: var(--spacer-lg);
|
|
65
|
+
padding-bottom: var(--spacer-lg);
|
|
68
66
|
container-type: inline-size;
|
|
69
67
|
}
|
|
70
68
|
|
|
@@ -73,38 +71,11 @@ h1 {
|
|
|
73
71
|
font-size: var(--font-base);
|
|
74
72
|
border-bottom: var(--border);
|
|
75
73
|
padding: 0 0 var(--spacer-sm);
|
|
76
|
-
margin: 0 0 var(--spacer
|
|
74
|
+
margin: 0 0 var(--spacer);
|
|
77
75
|
}
|
|
78
76
|
|
|
79
|
-
.
|
|
77
|
+
.token-mint-timeline-items {
|
|
80
78
|
display: grid;
|
|
81
79
|
gap: var(--spacer);
|
|
82
|
-
|
|
83
|
-
:deep(> div) {
|
|
84
|
-
display: grid;
|
|
85
|
-
gap: var(--spacer);
|
|
86
|
-
|
|
87
|
-
.right {
|
|
88
|
-
text-align: right;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
span {
|
|
92
|
-
white-space: nowrap;
|
|
93
|
-
|
|
94
|
-
&:nth-child(3) {
|
|
95
|
-
display: none;
|
|
96
|
-
|
|
97
|
-
@container (min-width: 30rem) {
|
|
98
|
-
display: inline;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
grid-template-columns: 6rem 3rem 1fr 3rem;
|
|
104
|
-
|
|
105
|
-
@container (min-width: 30rem) {
|
|
106
|
-
grid-template-columns: 6rem 3rem 1fr 6rem 1rem;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
80
|
}
|
|
110
81
|
</style>
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<
|
|
4
|
-
<Account :address="mint.address" />
|
|
5
|
-
</span>
|
|
2
|
+
<div class="token-mint-timeline-item">
|
|
3
|
+
<slot>
|
|
4
|
+
<Account :address="mint.address" class="account" />
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
<span class="amount">{{ mint.amount.toString() }}<span>×</span></span>
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
<span class="price">{{ formattedPrice.value }} {{ formattedPrice.format }}</span>
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
<span class="time-ago"><BlocksTimeAgo :blocks="block - mint.block" /></span>
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
<span class="links">
|
|
13
|
+
<NuxtLink :to="`${config.public.blockExplorer}/tx/${mint.tx}`" target="_blank">
|
|
14
|
+
<Icon type="link" />
|
|
15
|
+
</NuxtLink>
|
|
16
|
+
</span>
|
|
17
|
+
</slot>
|
|
18
18
|
</div>
|
|
19
19
|
</template>
|
|
20
20
|
|
|
@@ -29,5 +29,42 @@ const props = defineProps({
|
|
|
29
29
|
const formattedPrice = computed(() => customFormatEther(props.mint.price))
|
|
30
30
|
</script>
|
|
31
31
|
|
|
32
|
-
<style
|
|
32
|
+
<style>
|
|
33
|
+
.token-mint-timeline-item {
|
|
34
|
+
display: grid;
|
|
35
|
+
gap: 0 var(--spacer-sm);
|
|
36
|
+
grid-template-columns: 1fr 1fr;
|
|
37
|
+
|
|
38
|
+
.account {
|
|
39
|
+
grid-column: span 2;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.price,
|
|
43
|
+
.links {
|
|
44
|
+
text-align: right;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
span {
|
|
48
|
+
white-space: nowrap;
|
|
49
|
+
|
|
50
|
+
&:not(.account) {
|
|
51
|
+
color: var(--muted);
|
|
52
|
+
font-size: var(--font-sm);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@container (min-width: 24rem) {
|
|
57
|
+
grid-template-columns: 6rem 3rem 1fr 1fr 2rem;
|
|
58
|
+
gap: var(--spacer);
|
|
59
|
+
|
|
60
|
+
.account {
|
|
61
|
+
grid-column: 1;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.time-ago,
|
|
65
|
+
.amount {
|
|
66
|
+
text-align: right;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
33
70
|
</style>
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
<div class="content">
|
|
17
17
|
<header>
|
|
18
18
|
<h1>
|
|
19
|
-
<span>{{ token.name }} <span class="
|
|
20
|
-
<span v-if="token.description">{{ shortString(token.description, 60, 30) }}</span>
|
|
19
|
+
<span>{{ token.name }} <span class="token-id">#{{ token.tokenId }}</span></span>
|
|
20
|
+
<span v-if="token.description" class="description">{{ shortString(token.description, 60, 30) }}</span>
|
|
21
21
|
</h1>
|
|
22
|
-
<p v-if="mintOpen" class="
|
|
23
|
-
<p v-else class="
|
|
22
|
+
<p v-if="mintOpen" class="closes-in">Closes in {{ blocksRemaining }} {{ pluralize('block', Number(blocksRemaining))}}</p>
|
|
23
|
+
<p v-else class="closed-at">Closed at block {{ token.untilBlock }}</p>
|
|
24
24
|
</header>
|
|
25
|
-
<Image :src="token.artifact" :alt="token.name"
|
|
25
|
+
<Image :src="token.artifact" :alt="token.name" />
|
|
26
26
|
<CardLink :to="{
|
|
27
27
|
name: 'id-collection-tokenId',
|
|
28
28
|
params: { id: collection.owner, collection: token.collection, tokenId: `${token.tokenId}` }
|
|
@@ -69,19 +69,11 @@ const ownedBalance = computed(() => store.tokenBalance(collection.value.address,
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
.token-overview-card {
|
|
72
|
-
padding: var(--spacer-xl) var(--spacer)
|
|
73
|
-
|
|
74
|
-
/* Tokens should be at min the screen height. */
|
|
75
|
-
&:not(:first-of-type) {
|
|
76
|
-
min-height: min(60rem, calc(100dvh - 2*var(--navbar-height)));
|
|
77
|
-
|
|
78
|
-
@media (--md) {
|
|
79
|
-
min-height: min(60rem, calc(100dvh - var(--navbar-height)));
|
|
80
|
-
}
|
|
81
|
-
}
|
|
72
|
+
padding: var(--spacer-xl) var(--spacer);
|
|
73
|
+
min-height: min(60rem, 100dvh);
|
|
82
74
|
|
|
83
75
|
> p {
|
|
84
|
-
color: var(--
|
|
76
|
+
color: var(--);
|
|
85
77
|
font-size: var(--font-sm);
|
|
86
78
|
text-align: left;
|
|
87
79
|
}
|
|
@@ -108,7 +100,8 @@ const ownedBalance = computed(() => store.tokenBalance(collection.value.address,
|
|
|
108
100
|
|
|
109
101
|
h1 {
|
|
110
102
|
span:last-of-type:not(:first-child) {
|
|
111
|
-
color: var(--muted
|
|
103
|
+
color: var(--muted);
|
|
104
|
+
font-size: var(--font-sm);
|
|
112
105
|
white-space: wrap;
|
|
113
106
|
display: none;
|
|
114
107
|
|