@@ -9,9 +9,9 @@ | |||||
"lint": "vue-cli-service lint" | "lint": "vue-cli-service lint" | ||||
}, | }, | ||||
"dependencies": { | "dependencies": { | ||||
"@mdi/js": "^7.0.96", | |||||
"@jamescoyle/vue-icon": "^0.1.2", | |||||
"@mdi/js": "^7.1.96", | |||||
"@vueuse/core": "^9.5.0", | "@vueuse/core": "^9.5.0", | ||||
"bulma": "^0.9.4", | |||||
"core-js": "^3.8.3", | "core-js": "^3.8.3", | ||||
"jenesius-vue-modal": "^1.8.2", | "jenesius-vue-modal": "^1.8.2", | ||||
"jwt-decode": "^3.1.2", | "jwt-decode": "^3.1.2", | ||||
@@ -1,34 +1,14 @@ | |||||
<template> | <template> | ||||
<nav class="navbar has-background-grey-dark" role="navigation" aria-label="main navigation"> | |||||
<div class="navbar-brand"> | |||||
<RouterLink to="/" class="navbar-item"> | |||||
<span class="signet-logo title is-3-desktop is-4-mobile"> | |||||
<nav role="navigation" aria-label="main navigation"> | |||||
<div class="signet-logo"> | |||||
<RouterLink to="/"> | |||||
<span> | |||||
<template v-for="(element, i) in logoElements" v-bind:key="i"> | <template v-for="(element, i) in logoElements" v-bind:key="i"> | ||||
<span :style="`color: #${element.color}`">{{ element.letter }}</span> | |||||
<span :style="`color: ${element.color}`">{{ element.letter }}</span> | |||||
</template> | </template> | ||||
</span> | </span> | ||||
</RouterLink> | </RouterLink> | ||||
</div> | </div> | ||||
<div class="navbar-end"> | |||||
<div class="navbar-item"> | |||||
<div class="buttons is-hidden-mobile is-hidden-tablet-only"> | |||||
<div class="authentication" v-if="!hasToken"> | |||||
<RouterLink to="/login" class="button is-primary"> | |||||
Log in | |||||
</RouterLink> | |||||
</div> | |||||
<div v-else> | |||||
<RouterLink to="/addfund" class="button is-primary"> | |||||
Add Fund | |||||
</RouterLink> | |||||
<RouterLink to="/register" class="button is-white"> | |||||
Register | |||||
</RouterLink> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</nav> | </nav> | ||||
<div id="content"> | <div id="content"> | ||||
@@ -37,9 +17,11 @@ | |||||
<Component :is="Component"/> | <Component :is="Component"/> | ||||
<template #fallback> | <template #fallback> | ||||
<div class="is-flex is-flex-direction-row is-justify-content-center" | |||||
style="height: 90vh"> | |||||
<span style="font-size: 1.25em; color: greenyellow; margin: auto 0">Loading...</span> | |||||
<div | |||||
style="height: 90vh"> | |||||
<span style="font-size: 1.25em; color: greenyellow; margin: auto 0"> | |||||
Loading... | |||||
</span> | |||||
</div> | </div> | ||||
</template> | </template> | ||||
</Suspense> | </Suspense> | ||||
@@ -49,7 +31,7 @@ | |||||
<footer> | <footer> | ||||
<div> | <div> | ||||
Proudly made in Michigan | Proudly made in Michigan | ||||
<div class="michigan-icon"></div> | |||||
<div></div> | |||||
</div> | </div> | ||||
</footer> | </footer> | ||||
</template> | </template> | ||||
@@ -83,42 +65,65 @@ interface LogoElement { | |||||
color: string; | color: string; | ||||
} | } | ||||
const logoElements: LogoElement[] = [ | |||||
{ | |||||
color: '9fe82c', | |||||
letter: 'B', | |||||
}, | |||||
{ | |||||
color: '8ee045', | |||||
letter: 'e', | |||||
}, | |||||
{ | |||||
color: '7dd95c', | |||||
letter: 'i', | |||||
}, | |||||
{ | |||||
color: '6dd373', | |||||
letter: 'g', | |||||
}, | |||||
{ | |||||
color: '5dcb8a', | |||||
letter: 'n', | |||||
}, | |||||
{ | |||||
color: '4cc4a2', | |||||
letter: 'e', | |||||
}, | |||||
{ | |||||
color: '3dbeb8', | |||||
letter: 't', | |||||
}, | |||||
]; | |||||
const gradientize = (text: string, start: string, end: string): LogoElement[] => { | |||||
const extractChannels = (hex: string): { 'r': number, 'g': number, 'b': number } => { | |||||
const h = ref(hex); | |||||
if (h.value.startsWith('#')) { | |||||
h.value = hex.slice(1); | |||||
} else { | |||||
h.value = hex; | |||||
} | |||||
const [r, g, b] = [ | |||||
parseInt(h.value.slice(0, 2), 16), | |||||
parseInt(h.value.slice(2, 4), 16), | |||||
parseInt(h.value.slice(4, 6), 16), | |||||
]; | |||||
return { | |||||
r, | |||||
g, | |||||
b, | |||||
}; | |||||
}; | |||||
const composeHex = (r: number, g: number, b: number) => { | |||||
const padIfNeeded = (hex: string) => (hex.length === 1 ? `0${hex}` : hex); | |||||
const [rHex, gHex, bHex] = [ | |||||
`${padIfNeeded(r.toString(16))}`, | |||||
`${padIfNeeded(g.toString(16))}`, | |||||
`${padIfNeeded(b.toString(16))}`, | |||||
]; | |||||
return `#${rHex}${gHex}${bHex}`; | |||||
}; | |||||
const logoElements = ref([] as LogoElement[]); | |||||
const startChannels = extractChannels(start); | |||||
const endChannels = extractChannels(end); | |||||
const differences = { | |||||
r: endChannels.r - startChannels.r, | |||||
g: endChannels.g - startChannels.g, | |||||
b: endChannels.b - startChannels.b, | |||||
}; | |||||
const [r, g, b] = [ref(startChannels.r), ref(startChannels.g), ref(startChannels.b)]; | |||||
for (let i = 0; i < text.length; i += 1) { | |||||
r.value += differences.r / text.length; | |||||
g.value += differences.g / text.length; | |||||
b.value += differences.b / text.length; | |||||
logoElements.value.push({ | |||||
color: composeHex(Math.round(r.value), Math.round(g.value), Math.round(b.value)), | |||||
letter: text[i], | |||||
}); | |||||
} | |||||
return logoElements.value; | |||||
}; | |||||
const logoElements: LogoElement[] = gradientize('Beignet', '#f23525', '#e99406'); | |||||
</script> | </script> | ||||
<style lang="stylus"> | <style lang="stylus"> | ||||
@import "../node_modules/bulma/css/bulma.min.css" | |||||
@import "assets/styles/general.styl" | |||||
#content | #content | ||||
margin-top 1.5em | |||||
min-height 80vh | min-height 80vh | ||||
#app | #app | ||||
@@ -132,8 +137,8 @@ html, body | |||||
body | body | ||||
min-height 100vh | min-height 100vh | ||||
color #e8dbca | |||||
background-color #313538 | |||||
color text-color | |||||
background-color bg-color | |||||
footer | footer | ||||
color #707070 | color #707070 | ||||
@@ -144,9 +149,18 @@ footer | |||||
vertical-align middle | vertical-align middle | ||||
text-align center | text-align center | ||||
nav | |||||
background-color bg-color | |||||
padding 0.15em 0.7em | |||||
filter signet-shadow | |||||
a | |||||
text-decoration none | |||||
.signet-logo | .signet-logo | ||||
font-family Paytone | font-family Paytone | ||||
letter-spacing 1px | letter-spacing 1px | ||||
font-size 3em | |||||
.michigan-icon | .michigan-icon | ||||
display inline-block | display inline-block | ||||
@@ -158,10 +172,25 @@ footer | |||||
background-size 28px | background-size 28px | ||||
margin-left 4px | margin-left 4px | ||||
.navbar-burger > * | |||||
background-color #fff !important | |||||
.layout-section | |||||
margin 0 auto | |||||
width 61.8034% | |||||
@media screen and (max-width: 1080px) | |||||
width 82% | |||||
@media screen and (max-width: 860px) | |||||
width 96% | |||||
@font-face | @font-face | ||||
font-family Paytone | font-family Paytone | ||||
src url("./assets/PaytoneOne-Regular.ttf") | src url("./assets/PaytoneOne-Regular.ttf") | ||||
@font-face | |||||
font-family "Passion One" | |||||
src url("./assets/PassionOne-Regular.ttf") | |||||
@font-face | |||||
font-family "Passion One Bold" | |||||
src url("./assets/PassionOne-Bold.ttf") | |||||
</style> | </style> |
@@ -0,0 +1,9 @@ | |||||
text-color = #383838 | |||||
bg-color = #fffbfa | |||||
primary = #f23525 | |||||
secondary = #e99406 | |||||
signet-shadow = drop-shadow(0 0 3px #222222) | |||||
.heading | |||||
font-size 2em |
@@ -1,5 +1,5 @@ | |||||
<template> | <template> | ||||
<div class="is-flex is-flex-direction-row is-justify-content-space-between"> | |||||
<div> | |||||
<div class="select mr-1"> | <div class="select mr-1"> | ||||
<select | <select | ||||
ref="queueOptions" | ref="queueOptions" | ||||
@@ -25,13 +25,13 @@ | |||||
> | > | ||||
</div> | </div> | ||||
<div v-else-if="queueSelection >= 0" class="is-flex-grow-1 ml-1"> | <div v-else-if="queueSelection >= 0" class="is-flex-grow-1 ml-1"> | ||||
<Draggable :list="queueMembers" tag="div" class="edit-queue-list" @change="reorder"> | |||||
<Draggable :list="queueMembers" tag="div" @change="reorder"> | |||||
<div | <div | ||||
class="p-2 has-background-grey-dark edit-queue-list-item" | class="p-2 has-background-grey-dark edit-queue-list-item" | ||||
v-for="element in queueMembers" | v-for="element in queueMembers" | ||||
:key="element.order" | :key="element.order" | ||||
> | > | ||||
<div class="is-flex is-flex-direction-row is-justify-content-space-between"> | |||||
<div> | |||||
<div>{{ element.title }} ({{ element.asset }})</div> | <div>{{ element.title }} ({{ element.asset }})</div> | ||||
<div>{{ element.order }}</div> | <div>{{ element.order }}</div> | ||||
</div> | </div> | ||||
@@ -65,7 +65,7 @@ interface QueueMember { | |||||
} | } | ||||
// eslint-disable-next-line no-undef | // eslint-disable-next-line no-undef | ||||
const props = defineProps<{ newMember: RewardFund & { order: number; } }>(); | |||||
const props = defineProps<{ newMember: RewardFund & { order: number; } | undefined }>(); | |||||
// eslint-disable-next-line no-undef | // eslint-disable-next-line no-undef | ||||
const emits = defineEmits(['selected', 'created']); | const emits = defineEmits(['selected', 'created']); | ||||
@@ -111,17 +111,20 @@ const populateQueueMembers = async (id: number) => { | |||||
asset: m.asset, | asset: m.asset, | ||||
order: m.order, | order: m.order, | ||||
})); | })); | ||||
serverQueues.value = queueMembers.value.length; | |||||
if (queueMembers.value && props.newMember.title && props.newMember.asset) { | |||||
const newMember = { | |||||
id: undefined, | |||||
title: props.newMember.title, | |||||
asset: props.newMember.asset, | |||||
order: queueMembers.value.length + 1, | |||||
}; | |||||
if (props.newMember) { | |||||
serverQueues.value = queueMembers.value.length; | |||||
if (queueMembers.value && props.newMember.title && props.newMember.asset) { | |||||
const newMember = { | |||||
id: undefined, | |||||
title: props.newMember.title, | |||||
asset: props.newMember.asset, | |||||
order: queueMembers.value.length + 1, | |||||
}; | |||||
queueMembers.value.push(newMember); | |||||
queueMembers.value.push(newMember); | |||||
} | |||||
} | } | ||||
}; | }; | ||||
@@ -134,7 +137,7 @@ watch(queueSelection, async (newValue) => { | |||||
const addedMember = computed(() => props.newMember); | const addedMember = computed(() => props.newMember); | ||||
watch(addedMember, (newVal) => { | watch(addedMember, (newVal) => { | ||||
if (newVal.title && newVal.asset) { | |||||
if (newVal && newVal.title && newVal.asset) { | |||||
const assembleNewMember = (order: number) => ({ | const assembleNewMember = (order: number) => ({ | ||||
id: undefined, | id: undefined, | ||||
title: newVal.title, | title: newVal.title, | ||||
@@ -1,9 +1,9 @@ | |||||
<template> | <template> | ||||
<article class="message is-danger"> | |||||
<div class="message-header"> | |||||
<article> | |||||
<div> | |||||
<p>Errors</p> | <p>Errors</p> | ||||
</div> | </div> | ||||
<div class="message-body"> | |||||
<div> | |||||
<ol class="ml-2"> | <ol class="ml-2"> | ||||
<template v-for="(err, i) in props.errors" v-bind:key="i"> | <template v-for="(err, i) in props.errors" v-bind:key="i"> | ||||
<li v-show="err.condition"> | <li v-show="err.condition"> | ||||
@@ -1,25 +1,24 @@ | |||||
<template> | <template> | ||||
<div class="card py-2 px-4 has-text-dark" | |||||
:style="generateBackgroundStyle(`${fund.asset} ${fund.title}`)"> | |||||
<div class="is-size-2-desktop is-size-2-tablet is-size-3-mobile"> | |||||
<div class="fund-link"> | |||||
<div class="fund-name"> | |||||
{{ fund.asset }} | {{ fund.asset }} | ||||
</div> | </div> | ||||
<div> | <div> | ||||
<ul class="is-flex is-flex-direction-row is-justify-content-space-between"> | |||||
<li class="is-size-7 is-inline-block px-2"> | |||||
<span class="stellar-icon-base coin"></span> | |||||
<ul class="fund-details"> | |||||
<li> | |||||
<svg-icon type="mdi" height="18" width="18" :path="mdiCircleMultipleOutline"/> | |||||
<span class="fund-label">{{ props.fund.minContribution.toLocaleString() }}</span> | <span class="fund-label">{{ props.fund.minContribution.toLocaleString() }}</span> | ||||
</li> | </li> | ||||
<li class="is-size-7 is-inline-block px-2"> | |||||
<span class="stellar-icon-base goal"></span> | |||||
<li> | |||||
<svg-icon type="mdi" height="18" width="18" :path="mdiBullseyeArrow"/> | |||||
<span class="fund-label">{{ props.fund.amountAvailable.toLocaleString() }}</span> | <span class="fund-label">{{ props.fund.amountAvailable.toLocaleString() }}</span> | ||||
</li> | </li> | ||||
<li class="is-size-7 is-inline-block px-2"> | |||||
<span class="stellar-icon-base memo"></span> | |||||
<li> | |||||
<svg-icon type="mdi" height="18" width="18" :path="mdiNoteTextOutline"/> | |||||
<span class="fund-label">{{ props.fund.memo }}</span> | <span class="fund-label">{{ props.fund.memo }}</span> | ||||
</li> | </li> | ||||
<li class="is-size-7 is-inline-block px-2"> | |||||
<span class="stellar-icon-base wallet"></span> | |||||
<li> | |||||
<svg-icon type="mdi" height="18" width="18" :path="mdiWalletOutline"/> | |||||
<span class="fund-label"> | <span class="fund-label"> | ||||
{{ truncateWallet(props.fund.fundWallet, 5, undefined) }} | {{ truncateWallet(props.fund.fundWallet, 5, undefined) }} | ||||
</span> | </span> | ||||
@@ -30,43 +29,69 @@ | |||||
</template> | </template> | ||||
<script setup lang="ts"> | <script setup lang="ts"> | ||||
import { truncateWallet } from '@/lib/helpers'; | import { truncateWallet } from '@/lib/helpers'; | ||||
import { | |||||
FundInfo, | |||||
} from '@/api/types'; | |||||
import { FundInfo } from '@/api/types'; | |||||
import { PropType } from 'vue'; | import { PropType } from 'vue'; | ||||
import SvgIcon from '@jamescoyle/vue-icon'; | |||||
import { | |||||
mdiBullseyeArrow, | |||||
mdiCircleMultipleOutline, | |||||
mdiNoteTextOutline, | |||||
mdiWalletOutline, | |||||
} from '@mdi/js'; | |||||
// eslint-disable-next-line no-undef | // eslint-disable-next-line no-undef | ||||
const props = defineProps({ fund: Object as PropType<FundInfo> }); | const props = defineProps({ fund: Object as PropType<FundInfo> }); | ||||
const generateHue = (seed: string) => seed.split('').map((c) => c.charCodeAt(0)).reduce((v1, v2) => v1 + v2) % 256; | |||||
const generateHue = (seed: string) => seed.split('') | |||||
.map((c) => c.charCodeAt(0)) | |||||
.reduce((v1, v2) => v1 + v2) % 256; | |||||
const generateBackgroundStyle = (hueSeed: string) => { | const generateBackgroundStyle = (hueSeed: string) => { | ||||
const hue = generateHue(hueSeed); | const hue = generateHue(hueSeed); | ||||
return `background-color: hsl(${hue}deg, 54%, 76%)`; | |||||
return `background-color: hsl(${hue}deg, 32%, 47%)`; | |||||
}; | }; | ||||
</script> | </script> | ||||
<style scoped lang="stylus"> | <style scoped lang="stylus"> | ||||
@import "../assets/styles/general.styl" | |||||
.fund-link | |||||
background-color bg-color | |||||
border-radius 8px | |||||
overflow hidden | |||||
filter signet-shadow | |||||
.fund-name | |||||
font-size 3em | |||||
margin 0.4em | |||||
color text-color | |||||
font-family "Passion One Bold" | |||||
font-weight 900 | |||||
.fund-label | .fund-label | ||||
color text-color | |||||
vertical-align top | vertical-align top | ||||
margin-left 6px | |||||
.stellar-icon-base | |||||
display inline-block | |||||
height 20px | |||||
width 20px | |||||
margin-right 4px | |||||
background-position center | |||||
background-size 16px | |||||
background-repeat no-repeat | |||||
&.coin | |||||
background-image url("../assets/icons8-expensive-24.png") | |||||
.fund-details | |||||
background-color secondary | |||||
display flex | |||||
flex-direction row | |||||
justify-content space-between | |||||
list-style none | |||||
padding 4px 10px 2px 10px | |||||
margin 0 | |||||
vertical-align middle | |||||
&.goal | |||||
background-image url("../assets/icons8-goal-48.png") | |||||
svg | |||||
color text-color | |||||
&.memo | |||||
background-image url("../assets/icons8-note-24.png") | |||||
@media screen and (max-width: 780px) | |||||
.fund-label | |||||
display inline-block | |||||
font-size 12px | |||||
vertical-align text-top | |||||
&.wallet | |||||
background-image url("../assets/icons8-wallet-24.png") | |||||
@media screen and (max-width: 300px) | |||||
.fund-label | |||||
font-size 10px | |||||
</style> | </style> |
@@ -1,36 +1,36 @@ | |||||
<template> | <template> | ||||
<div> | <div> | ||||
<table class="table is-fullwidth"> | |||||
<table> | |||||
<thead> | <thead> | ||||
<tr> | |||||
<th>Goal Amount</th> | |||||
<th>Percent Bonus</th> | |||||
</tr> | |||||
<tr> | |||||
<th>Goal Amount</th> | |||||
<th>Percent Bonus</th> | |||||
</tr> | |||||
</thead> | </thead> | ||||
<tbody> | <tbody> | ||||
<tr v-for="kv in bonuses" v-bind:key="kv.id"> | |||||
<td class="p-0"> | |||||
<input | |||||
type="text" | |||||
class="input is-small" | |||||
v-model="kv.goal" | |||||
:aria-label="`Goal #${bonuses.length}`" | |||||
@input="checkInputs" | |||||
@blur="saveValues" | |||||
> | |||||
</td> | |||||
<td class="p-0"> | |||||
<input | |||||
type="text" | |||||
class="input is-small" | |||||
:class="kv.percent < 1 ? 'is-danger' : ''" | |||||
v-model="kv.percent" | |||||
:aria-label="`Cashback percent #${bonuses.length}`" | |||||
@input="checkInputs" | |||||
@blur="saveValues" | |||||
> | |||||
</td> | |||||
</tr> | |||||
<tr v-for="kv in bonuses" v-bind:key="kv.id"> | |||||
<td class="p-0"> | |||||
<input | |||||
type="text" | |||||
v-model="kv.goal" | |||||
:aria-label="`Goal #${bonuses.length}`" | |||||
@input="checkInputs" | |||||
@blur="saveValues" | |||||
> | |||||
</td> | |||||
<td class="p-0"> | |||||
<input | |||||
type="text" | |||||
:class="kv.percent < 1 ? 'is-danger' : ''" | |||||
v-model="kv.percent" | |||||
:aria-label="`Cashback percent #${bonuses.length}`" | |||||
@input="checkInputs" | |||||
@blur="saveValues" | |||||
> | |||||
</td> | |||||
</tr> | |||||
</tbody> | </tbody> | ||||
</table> | </table> | ||||
</div> | </div> | ||||
@@ -48,22 +48,33 @@ interface Bonus { | |||||
// eslint-disable-next-line no-undef | // eslint-disable-next-line no-undef | ||||
const emits = defineEmits(['save']); | const emits = defineEmits(['save']); | ||||
const bonuses = ref([{ id: 1, goal: undefined, percent: undefined }] as Bonus[]); | |||||
const bonuses = ref([{ | |||||
id: 1, | |||||
goal: undefined, | |||||
percent: undefined, | |||||
}] as Bonus[]); | |||||
const getNextId = () => bonuses.value.length + 1; | const getNextId = () => bonuses.value.length + 1; | ||||
const checkInputs = () => { | const checkInputs = () => { | ||||
if (bonuses.value.every((b) => Object.values(b).every((v) => !!v))) { | |||||
if (bonuses.value.every((b) => Object.values(b) | |||||
.every((v) => !!v))) { | |||||
bonuses.value.push({ | bonuses.value.push({ | ||||
id: getNextId(), goal: undefined, percent: undefined, | |||||
id: getNextId(), | |||||
goal: undefined, | |||||
percent: undefined, | |||||
}); | }); | ||||
} | } | ||||
}; | }; | ||||
const saveValues = () => { | const saveValues = () => { | ||||
emits('save', bonuses.value.filter((b) => !!b.goal && !!b.percent).map((b) => ( | |||||
{ goal: parseFloat(b.goal as string), percent: parseFloat(b.percent as string) } | |||||
))); | |||||
emits('save', bonuses.value.filter((b) => !!b.goal && !!b.percent) | |||||
.map((b) => ( | |||||
{ | |||||
goal: parseFloat(b.goal as string), | |||||
percent: parseFloat(b.percent as string), | |||||
} | |||||
))); | |||||
}; | }; | ||||
</script> | </script> | ||||
@@ -1,5 +1,5 @@ | |||||
<template> | <template> | ||||
<div class="hello"> | |||||
<div> | |||||
<h1>{{ msg }}</h1> | <h1>{{ msg }}</h1> | ||||
<p> | <p> | ||||
For a guide and recipes on how to configure / customize this project,<br> | For a guide and recipes on how to configure / customize this project,<br> | ||||
@@ -8,12 +8,18 @@ | |||||
</p> | </p> | ||||
<h3>Installed CLI Plugins</h3> | <h3>Installed CLI Plugins</h3> | ||||
<ul> | <ul> | ||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha" target="_blank" rel="noopener">unit-mocha</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" | |||||
target="_blank" rel="noopener">babel</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" | |||||
target="_blank" rel="noopener">router</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" | |||||
target="_blank" rel="noopener">vuex</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" | |||||
target="_blank" rel="noopener">eslint</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-mocha" | |||||
target="_blank" rel="noopener">unit-mocha</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" | |||||
target="_blank" rel="noopener">typescript</a></li> | |||||
</ul> | </ul> | ||||
<h3>Essential Links</h3> | <h3>Essential Links</h3> | ||||
<ul> | <ul> | ||||
@@ -27,9 +33,11 @@ | |||||
<ul> | <ul> | ||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li> | <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li> | ||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li> | <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li> | ||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li> | |||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" | |||||
rel="noopener">vue-devtools</a></li> | |||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li> | <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li> | ||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li> | |||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" | |||||
rel="noopener">awesome-vue</a></li> | |||||
</ul> | </ul> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
@@ -1,31 +1,31 @@ | |||||
<template> | <template> | ||||
<div class="container is-max-desktop"> | |||||
<section class="section is-small"> | |||||
<div> | |||||
<section> | |||||
<div class="title is-4 has-text-white-ter has-text-centered">Add Fund</div> | <div class="title is-4 has-text-white-ter has-text-centered">Add Fund</div> | ||||
<section class="section px-0 py-4"> | <section class="section px-0 py-4"> | ||||
<div class="title is-5 has-text-white-ter">Post</div> | <div class="title is-5 has-text-white-ter">Post</div> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<input class="input is-normal has-background-white has-text-black" type="text" | |||||
<input type="text" | |||||
placeholder="Title" aria-label="Title" v-model="title"> | placeholder="Title" aria-label="Title" v-model="title"> | ||||
</div> | </div> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<textarea class="textarea is-normal has-background-white has-text-black" | |||||
placeholder="Description" aria-label="Description" v-model="description"> | |||||
<textarea | |||||
placeholder="Description" aria-label="Description" v-model="description"> | |||||
</textarea> | </textarea> | ||||
</div> | </div> | ||||
</section> | </section> | ||||
<section class="section px-0 py-4"> | <section class="section px-0 py-4"> | ||||
<div class="title is-5 has-text-white-ter">Wallet</div> | <div class="title is-5 has-text-white-ter">Wallet</div> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<input class="input is-normal has-background-white has-text-black" type="text" | |||||
<input type="text" | |||||
placeholder="Fund Wallet" aria-label="Fund Wallet" v-model="fundWallet"> | placeholder="Fund Wallet" aria-label="Fund Wallet" v-model="fundWallet"> | ||||
</div> | </div> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<input class="input is-normal has-background-white has-text-black" type="text" | |||||
<input type="text" | |||||
placeholder="Selling Wallet" aria-label="Selling Wallet" v-model="sellWallet"> | placeholder="Selling Wallet" aria-label="Selling Wallet" v-model="sellWallet"> | ||||
</div> | </div> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<input class="input is-normal has-background-white has-text-black" type="text" | |||||
<input type="text" | |||||
placeholder="Issuer Wallet" aria-label="Issuer Wallet" v-model="issuerWallet"> | placeholder="Issuer Wallet" aria-label="Issuer Wallet" v-model="issuerWallet"> | ||||
</div> | </div> | ||||
</section> | </section> | ||||
@@ -56,7 +56,7 @@ | |||||
</section> | </section> | ||||
<div class="buttons is-flex is-justify-content-end mt-5"> | <div class="buttons is-flex is-justify-content-end mt-5"> | ||||
<button | <button | ||||
class="button is-success" | |||||
:class="requesting ? 'is-loading' : ''" | :class="requesting ? 'is-loading' : ''" | ||||
@click="submit" | @click="submit" | ||||
>Submit | >Submit | ||||
@@ -1,8 +1,8 @@ | |||||
<template> | <template> | ||||
<!-- Unused --> | <!-- Unused --> | ||||
<div class="is-flex is-flex-direction-row"> | |||||
<nav class="is-hidden-tablet-only is-hidden-mobile has-background-white-ter"> | |||||
<div class="has-background-primary"> | |||||
<div> | |||||
<nav> | |||||
<div> | |||||
<span class="has-text-white has-text-weight-bold my-4 mx-2">Administration</span> | <span class="has-text-white has-text-weight-bold my-4 mx-2">Administration</span> | ||||
</div> | </div> | ||||
<ul class="p-2"> | <ul class="p-2"> | ||||
@@ -11,7 +11,7 @@ | |||||
</li> | </li> | ||||
</ul> | </ul> | ||||
</nav> | </nav> | ||||
<div class="container is-max-desktop"> | |||||
<div> | |||||
<RouterView></RouterView> | <RouterView></RouterView> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -19,9 +19,18 @@ | |||||
<script setup lang="ts"> | <script setup lang="ts"> | ||||
const links = [ | const links = [ | ||||
{ text: 'Add Fund', to: '/admin/addfund' }, | |||||
{ text: 'Modify Fund', to: '' }, | |||||
{ text: 'Create Tag', to: '' }, | |||||
{ | |||||
text: 'Add Fund', | |||||
to: '/admin/addfund', | |||||
}, | |||||
{ | |||||
text: 'Modify Fund', | |||||
to: '', | |||||
}, | |||||
{ | |||||
text: 'Create Tag', | |||||
to: '', | |||||
}, | |||||
]; | ]; | ||||
</script> | </script> | ||||
@@ -0,0 +1,11 @@ | |||||
<template> | |||||
</template> | |||||
<script setup lang="ts"> | |||||
</script> | |||||
<style scoped lang="stylus"> | |||||
</style> |
@@ -0,0 +1,14 @@ | |||||
<template> | |||||
<EditQueue :new-member="member"/> | |||||
</template> | |||||
<script setup lang="ts"> | |||||
import EditQueue from '@/components/EditQueue.vue'; | |||||
const member = null; | |||||
</script> | |||||
<style scoped lang="stylus"> | |||||
</style> |
@@ -1,48 +1,43 @@ | |||||
<template> | <template> | ||||
<div class="container is-max-desktop pb-4"> | |||||
<section class="section is-small"> | |||||
<div class="title is-size-4 has-text-white-ter has-text-centered"> | |||||
<div> | |||||
<section class="layout-section"> | |||||
<div class="heading"> | |||||
{{ fund.fundInfo.title }} | {{ fund.fundInfo.title }} | ||||
</div> | </div> | ||||
<div | |||||
class="is-block-mobile | |||||
is-flex-tablet-only | |||||
is-flex-desktop | |||||
is-flex-direction-row | |||||
is-justify-content-space-between"> | |||||
<div class="fund-description pr-5" v-html="fixNewlines(fund.fundInfo.description)"> | |||||
</div> | |||||
<div | |||||
class="fund-details is-flex is-flex-direction-row is-justify-content-end my-auto py-6"> | |||||
<ul> | |||||
<li v-for="(detail, i) in fundDetails" v-bind:key="i"> | |||||
<span class="has-text-weight-bold is-size-6 mr-2">{{ detail.title }}</span> | |||||
<span class="is-size-6">{{ detail.val }}</span> | |||||
<div> | |||||
<p v-html="fixNewlines(fund.fundInfo.description)"></p> | |||||
<div> | |||||
<ul class="fund-details"> | |||||
<li v-for="(detail, i) in fundDetails" :key="i" class="fund-detail"> | |||||
<div class="detail-icon"> | |||||
<svg-icon type="mdi" height="22" width="22" :path="detail.icon"/> | |||||
</div> | |||||
<div class="detail-text"> | |||||
{{ detail.val }} | |||||
</div> | |||||
</li> | </li> | ||||
</ul> | </ul> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</section> | |||||
<section> | |||||
<div class="box"> | |||||
<div class="title is-size-4 has-text-grey-dark has-text-centered"> | |||||
<div> | |||||
<div class="heading"> | |||||
Tracker | Tracker | ||||
</div> | </div> | ||||
<div class="level" v-if="fund.fundInfo.bonuses.length > 0"> | |||||
<div class="level-item has-text-centered" | |||||
v-for="bonus in fund.fundInfo.bonuses.sort((v1, v2) => v1.goal - v2.goal)" | |||||
v-bind:key="bonus.goal" | |||||
<div v-if="fund.fundInfo.bonuses.length > 0"> | |||||
<div | |||||
v-for="bonus in fund.fundInfo.bonuses.sort((v1, v2) => v1.goal - v2.goal)" | |||||
v-bind:key="bonus.goal" | |||||
> | > | ||||
<div> | <div> | ||||
<p | <p | ||||
class="heading" | |||||
:class="amountHeld >= bonus.goal | :class="amountHeld >= bonus.goal | ||||
? 'has-text-success' : 'has-text-grey-dark'" | ? 'has-text-success' : 'has-text-grey-dark'" | ||||
> | > | ||||
{{ bonus.goal.toLocaleString() }} XLM | {{ bonus.goal.toLocaleString() }} XLM | ||||
</p> | </p> | ||||
<p | <p | ||||
class="title" | |||||
:class="amountHeld >= bonus.goal | :class="amountHeld >= bonus.goal | ||||
? 'has-text-success' : 'has-text-grey-dark'" | ? 'has-text-success' : 'has-text-grey-dark'" | ||||
> | > | ||||
@@ -52,15 +47,8 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<div | |||||
class="is-flex | |||||
is-flex-direction-row | |||||
is-justify-content-space-around | |||||
is-size-4 | |||||
has-text-white | |||||
mb-3" | |||||
> | |||||
<div class="total"> | |||||
<div> | |||||
<div> | |||||
<span class="total-label is-size-3 pr-2 has-text-weight-light"> | <span class="total-label is-size-3 pr-2 has-text-weight-light"> | ||||
Raised | Raised | ||||
</span> | </span> | ||||
@@ -68,7 +56,7 @@ | |||||
{{ amountHeld.toLocaleString() }} XLM | {{ amountHeld.toLocaleString() }} XLM | ||||
</span> | </span> | ||||
</div> | </div> | ||||
<div class="remaining"> | |||||
<div> | |||||
<span class="remaining-label is-size-3 pr-2 has-text-weight-light"> | <span class="remaining-label is-size-3 pr-2 has-text-weight-light"> | ||||
Remaining | Remaining | ||||
</span> | </span> | ||||
@@ -77,19 +65,17 @@ | |||||
</span> | </span> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</section> | |||||
<section class="section is-small"> | |||||
<div class="title is-size-4 has-text-white-ter has-text-centered"> | <div class="title is-size-4 has-text-white-ter has-text-centered"> | ||||
Contribute | Contribute | ||||
</div> | </div> | ||||
<ErrorDisplay :errors="errs" v-if="invalidContributionForm"/> | <ErrorDisplay :errors="errs" v-if="invalidContributionForm"/> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<input class="input is-normal has-background-white has-text-black" type="text" | |||||
<input type="text" | |||||
placeholder="Private Key" aria-label="Wallet" v-model="pk" @blur="queryAccount"> | placeholder="Private Key" aria-label="Wallet" v-model="pk" @blur="queryAccount"> | ||||
</div> | </div> | ||||
<div class="control my-2" :class="loading.balance ? 'is-loading' : null"> | <div class="control my-2" :class="loading.balance ? 'is-loading' : null"> | ||||
<input | <input | ||||
class="input is-normal has-background-white has-text-black" | |||||
type="number" | type="number" | ||||
placeholder="Amount" | placeholder="Amount" | ||||
aria-label="Amount" | aria-label="Amount" | ||||
@@ -98,90 +84,89 @@ | |||||
:disabled="loading.balance" | :disabled="loading.balance" | ||||
> | > | ||||
</div> | </div> | ||||
<div class="is-flex is-justify-content-end"> | |||||
<div> | |||||
<button | <button | ||||
class="button is-primary" | |||||
:class="loading.contribution ? 'is-loading' : ''" | :class="loading.contribution ? 'is-loading' : ''" | ||||
:disabled="invalidContributionForm" | :disabled="invalidContributionForm" | ||||
@click="makeContribution" | @click="makeContribution" | ||||
>Submit | >Submit | ||||
</button> | </button> | ||||
</div> | </div> | ||||
</section> | |||||
<section class="section is-small" v-if="contributions.length > 0"> | |||||
<div class="title is-size-4 has-text-white-ter has-text-centered"> | |||||
Contributions | |||||
</div> | |||||
<div class="is-flex is-justify-content-space-between is-rounded my-2"> | |||||
<div class="select"> | |||||
<select v-model="selectedDate" aria-label="Filter by date"> | |||||
<option v-for="date in selectableDates" v-bind:key="date" :value="date"> | |||||
{{ date ?? 'Cutoff Date' }} | |||||
</option> | |||||
</select> | |||||
<section v-if="contributions.length > 0"> | |||||
<div class="title is-size-4 has-text-white-ter has-text-centered"> | |||||
Contributions | |||||
</div> | </div> | ||||
<div class="consolidate-option has-background-white px-4 py-1 my-auto"> | |||||
<label for="consolidate" class="checkbox has-text-dark is-size-6"> | |||||
<span class="consolidate-label is-inline-block"> | |||||
<div class="is-flex is-justify-content-space-between is-rounded my-2"> | |||||
<div> | |||||
<select v-model="selectedDate" aria-label="Filter by date"> | |||||
<option v-for="date in selectableDates" v-bind:key="date" :value="date"> | |||||
{{ date ?? 'Cutoff Date' }} | |||||
</option> | |||||
</select> | |||||
</div> | |||||
<div class="consolidate-option has-background-white px-4 py-1 my-auto"> | |||||
<label for="consolidate" class="checkbox has-text-dark is-size-6"> | |||||
<span> | |||||
Consolidate wallets | Consolidate wallets | ||||
</span> | </span> | ||||
<input | |||||
type="checkbox" | |||||
class="ml-2" | |||||
id="consolidate" | |||||
aria-label="Consolidate wallets" | |||||
v-model="enableConsolidation" | |||||
> | |||||
</label> | |||||
<input | |||||
type="checkbox" | |||||
class="ml-2" | |||||
id="consolidate" | |||||
aria-label="Consolidate wallets" | |||||
v-model="enableConsolidation" | |||||
> | |||||
</label> | |||||
</div> | |||||
</div> | </div> | ||||
</div> | |||||
<div id="contribution-container" @scroll="loadMoreIfNeeded"> | |||||
<table class="contribution-table table is-fullwidth"> | |||||
<thead> | |||||
<tr> | |||||
<th>Wallet</th> | |||||
<th>Amount</th> | |||||
<th v-if="!enableConsolidation">Time</th> | |||||
<th v-else>Tokens</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr v-for="(contribution, i) in contributions" v-bind:key="i"> | |||||
<td>{{ truncateWallet(contribution.wallet, 6, undefined) }}</td> | |||||
<td>{{ contribution.amount }}</td> | |||||
<td v-if="!enableConsolidation"> | |||||
<span class="transaction-date" :title="formatDate(contribution.createdAt, true)"> | |||||
<div id="contribution-container" @scroll="loadMoreIfNeeded"> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>Wallet</th> | |||||
<th>Amount</th> | |||||
<th v-if="!enableConsolidation">Time</th> | |||||
<th v-else>Tokens</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr v-for="(contribution, i) in contributions" v-bind:key="i"> | |||||
<td>{{ truncateWallet(contribution.wallet, 6, undefined) }}</td> | |||||
<td>{{ contribution.amount }}</td> | |||||
<td v-if="!enableConsolidation"> | |||||
<span :title="formatDate(contribution.createdAt, true)"> | |||||
{{ formatDate(contribution.createdAt, true) }} | {{ formatDate(contribution.createdAt, true) }} | ||||
</span> | </span> | ||||
</td> | |||||
<td v-else> | |||||
<span>{{ calculateReward(contribution.amount / fund.fundInfo.price) }}</span> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</section> | |||||
<section v-if="store.getters.getToken && hasPermission(Privileges.AdminPlus)"> | |||||
<div class="title is-size-4 has-text-white-ter has-text-centered"> | |||||
Close Group Fund | |||||
</div> | |||||
<div class="box is-flex is-flex-direction-row is-justify-content-space-between"> | |||||
<div class="my-auto"> | |||||
<label class="checkbox" for="delete-confirm"> | |||||
<input type="checkbox" id="delete-confirm" v-model="allowDelete"> Close | |||||
</label> | |||||
</td> | |||||
<td v-else> | |||||
<span>{{ calculateReward(contribution.amount / fund.fundInfo.price) }}</span> | |||||
</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</section> | |||||
<section v-if="store.getters.getToken && hasPermission(Privileges.AdminPlus)"> | |||||
<div class="title is-size-4 has-text-white-ter has-text-centered"> | |||||
Close Group Fund | |||||
</div> | </div> | ||||
<div> | <div> | ||||
<button | |||||
class="button is-danger" | |||||
:disabled="!allowDelete" | |||||
@click="deleteFund" | |||||
> | |||||
Close | |||||
</button> | |||||
<div> | |||||
<label for="delete-confirm"> | |||||
<input type="checkbox" id="delete-confirm" v-model="allowDelete"> Close | |||||
</label> | |||||
</div> | |||||
<div> | |||||
<button | |||||
:disabled="!allowDelete" | |||||
@click="deleteFund" | |||||
> | |||||
Close | |||||
</button> | |||||
</div> | |||||
</div> | </div> | ||||
</div> | |||||
</section> | |||||
</section> | </section> | ||||
</div> | </div> | ||||
</template> | </template> | ||||
@@ -220,6 +205,13 @@ import { | |||||
getContributions, | getContributions, | ||||
getRewardFund, | getRewardFund, | ||||
} from '@/api/composed'; | } from '@/api/composed'; | ||||
import SvgIcon from '@jamescoyle/vue-icon'; | |||||
import { | |||||
mdiCircleMultipleOutline, | |||||
mdiGreaterThanOrEqual, | |||||
mdiNoteTextOutline, | |||||
mdiTarget, | |||||
} from '@mdi/js'; | |||||
const route = useRoute(); | const route = useRoute(); | ||||
const router = useRouter(); | const router = useRouter(); | ||||
@@ -260,7 +252,7 @@ const fund = ref( | |||||
} as GetRewardFundResponse | null, | } as GetRewardFundResponse | null, | ||||
); | ); | ||||
const fundDetails = ref([{ | const fundDetails = ref([{ | ||||
title: '', | |||||
icon: '', | |||||
val: '', | val: '', | ||||
}]); | }]); | ||||
@@ -271,19 +263,19 @@ if (!fund.value) { | |||||
} | } | ||||
fundDetails.value = [ | fundDetails.value = [ | ||||
{ | { | ||||
title: 'Asset', | |||||
icon: mdiCircleMultipleOutline, | |||||
val: fund.value.fundInfo.asset, | val: fund.value.fundInfo.asset, | ||||
}, | }, | ||||
{ | { | ||||
title: 'Min', | |||||
icon: mdiGreaterThanOrEqual, | |||||
val: `${fund.value.fundInfo.minContribution.toLocaleString()}`, | val: `${fund.value.fundInfo.minContribution.toLocaleString()}`, | ||||
}, | }, | ||||
{ | { | ||||
title: 'Goal', | |||||
icon: mdiTarget, | |||||
val: `${fund.value.fundInfo.amountAvailable.toLocaleString()}`, | val: `${fund.value.fundInfo.amountAvailable.toLocaleString()}`, | ||||
}, | }, | ||||
{ | { | ||||
title: 'Memo', | |||||
icon: mdiNoteTextOutline, | |||||
val: `"${fund.value.fundInfo.memo}"`, | val: `"${fund.value.fundInfo.memo}"`, | ||||
}, | }, | ||||
]; | ]; | ||||
@@ -528,14 +520,27 @@ watch(data, (newVal) => { | |||||
min-height 280px | min-height 280px | ||||
.fund-details | .fund-details | ||||
width 182px | |||||
display flex | |||||
flex-direction row | |||||
justify-content space-around | |||||
background-color darkorange | |||||
border-radius 4px | |||||
list-style-type none | |||||
margin 0 | |||||
padding 8px 4px | |||||
.detail-icon | |||||
display flex | |||||
justify-content center | |||||
color #fff | |||||
margin-bottom 8px | |||||
.detail-text | |||||
font-size 16px | |||||
text-align center | |||||
color #fff | |||||
font-family "Passion One" | |||||
#consolidate | #consolidate | ||||
vertical-align middle | vertical-align middle | ||||
@media screen and (min-width: 1024px) | |||||
.fund-details | |||||
max-width 14vw | |||||
border-left 1px #777 solid | |||||
padding-left 10px | |||||
</style> | </style> |
@@ -1,8 +1,8 @@ | |||||
<template> | <template> | ||||
<div class="container is-max-desktop"> | |||||
<section class="section is-small px-0"> | |||||
<div> | |||||
<section class="layout-section"> | |||||
<div class="container-grid" v-if="rewardFunds"> | <div class="container-grid" v-if="rewardFunds"> | ||||
<template v-for="fund in rewardFunds" v-bind:key="fund.id"> | |||||
<template v-for="fund in rewardFunds" :key="fund.id"> | |||||
<RouterLink :to="`/fund/${fund.id}`"> | <RouterLink :to="`/fund/${fund.id}`"> | ||||
<FundLink :fund="fund"/> | <FundLink :fund="fund"/> | ||||
</RouterLink> | </RouterLink> | ||||
@@ -36,11 +36,14 @@ offset.value = total; | |||||
<style scoped lang="stylus"> | <style scoped lang="stylus"> | ||||
.container-grid | .container-grid | ||||
display grid | display grid | ||||
grid-template-columns: repeat(2, 1fr); | |||||
gap: 10px; | |||||
grid-auto-rows: 120px; | |||||
grid-template-columns: repeat(2, 1fr) | |||||
gap: 10px | |||||
grid-auto-rows: 120px | |||||
@media screen and (max-width: 768px) | |||||
a | |||||
text-decoration none | |||||
@media screen and (max-width: 680px) | |||||
.container-grid | .container-grid | ||||
display flex | display flex | ||||
flex-direction column | flex-direction column | ||||
@@ -1,17 +1,17 @@ | |||||
<template> | <template> | ||||
<div class="container is-max-desktop"> | |||||
<section class="section is-large"> | |||||
<div> | |||||
<section> | |||||
<div class="title is-4 has-text-white-ter has-text-centered">Login</div> | <div class="title is-4 has-text-white-ter has-text-centered">Login</div> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<input class="input is-medium" type="text" placeholder="Username" | |||||
<input type="text" placeholder="Username" | |||||
aria-label="Username" v-model="username" @keyup.enter="submit"> | aria-label="Username" v-model="username" @keyup.enter="submit"> | ||||
</div> | </div> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<input class="input is-medium" type="password" placeholder="Password" | |||||
<input type="password" placeholder="Password" | |||||
aria-label="Password" v-model="password" @keyup.enter="submit"> | aria-label="Password" v-model="password" @keyup.enter="submit"> | ||||
</div> | </div> | ||||
<div class="buttons is-flex is-justify-content-end mt-5"> | <div class="buttons is-flex is-justify-content-end mt-5"> | ||||
<button class="button is-success" @click="submit">Submit</button> | |||||
<button @click="submit">Submit</button> | |||||
</div> | </div> | ||||
</section> | </section> | ||||
</div> | </div> | ||||
@@ -1,17 +1,17 @@ | |||||
<template> | <template> | ||||
<div class="container is-max-desktop"> | |||||
<section class="section is-large"> | |||||
<div> | |||||
<section> | |||||
<div class="title is-4 has-text-white-ter has-text-centered">Register</div> | <div class="title is-4 has-text-white-ter has-text-centered">Register</div> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<input class="input is-medium" type="text" placeholder="Username" | |||||
<input type="text" placeholder="Username" | |||||
aria-label="Username" v-model="username"> | aria-label="Username" v-model="username"> | ||||
</div> | </div> | ||||
<div class="control my-2"> | <div class="control my-2"> | ||||
<input class="input is-medium" type="password" placeholder="Password" | |||||
<input type="password" placeholder="Password" | |||||
aria-label="Password" v-model="password"> | aria-label="Password" v-model="password"> | ||||
</div> | </div> | ||||
<div class="buttons is-flex is-justify-content-end mt-5"> | <div class="buttons is-flex is-justify-content-end mt-5"> | ||||
<button class="button is-success" @click="submit">Submit</button> | |||||
<button @click="submit">Submit</button> | |||||
</div> | </div> | ||||
</section> | </section> | ||||
</div> | </div> | ||||
@@ -1002,6 +1002,11 @@ | |||||
resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" | resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" | ||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== | integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== | ||||
"@jamescoyle/vue-icon@^0.1.2": | |||||
version "0.1.2" | |||||
resolved "https://registry.yarnpkg.com/@jamescoyle/vue-icon/-/vue-icon-0.1.2.tgz#b9e254187de6716b81bf9e0e8400ec012231bd05" | |||||
integrity sha512-KFrImXx5TKIi6iQXlnyLEBl4rNosNKbTeRnr70ucTdUaciVmd9qK9d/pZAaKt1Ob/8xNnX2GMp8LisyHdKtEgw== | |||||
"@jridgewell/gen-mapping@^0.1.0": | "@jridgewell/gen-mapping@^0.1.0": | ||||
version "0.1.1" | version "0.1.1" | ||||
resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz" | resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz" | ||||
@@ -1055,10 +1060,10 @@ | |||||
resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz" | resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz" | ||||
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== | integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== | ||||
"@mdi/js@^7.0.96": | |||||
version "7.0.96" | |||||
resolved "https://registry.npmjs.org/@mdi/js/-/js-7.0.96.tgz" | |||||
integrity sha512-lNqhkV3cpPfYb/Avh+vXLFukUTbHbyHoFo4Jdc7Oc9UvURGVhamFIpgOVvEf2bNA78zvjXTZeVWExUTR+DLBfQ== | |||||
"@mdi/js@^7.1.96": | |||||
version "7.1.96" | |||||
resolved "https://registry.yarnpkg.com/@mdi/js/-/js-7.1.96.tgz#9c5a7f8a20ea63c03b09a0dba1768fe8b70eeaf9" | |||||
integrity sha512-wlrJs6Ryhaa5CqhK3FjTfMRnb/s7HeLkKMFqwQySkK86cdN1TGdzpSM3O4tsmzCA1dYBeTbXvOwSE/Y42cUrvA== | |||||
"@node-ipc/js-queue@2.0.3": | "@node-ipc/js-queue@2.0.3": | ||||
version "2.0.3" | version "2.0.3" | ||||
@@ -2440,11 +2445,6 @@ buffer@^5.5.0: | |||||
base64-js "^1.3.1" | base64-js "^1.3.1" | ||||
ieee754 "^1.1.13" | ieee754 "^1.1.13" | ||||
bulma@^0.9.4: | |||||
version "0.9.4" | |||||
resolved "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz" | |||||
integrity sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ== | |||||
bytes@3.0.0: | bytes@3.0.0: | ||||
version "3.0.0" | version "3.0.0" | ||||
resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" | resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" | ||||