| @@ -19,8 +19,8 @@ | |||||
| </RouterLink> | </RouterLink> | ||||
| </div> | </div> | ||||
| <div v-else> | <div v-else> | ||||
| <RouterLink to="/addfund" class="button is-primary"> | |||||
| Add Fund | |||||
| <RouterLink to="/admin/dashboard" class="button is-primary"> | |||||
| Admin | |||||
| </RouterLink> | </RouterLink> | ||||
| <RouterLink to="/register" class="button is-white"> | <RouterLink to="/register" class="button is-white"> | ||||
| Register | Register | ||||
| @@ -7,6 +7,7 @@ import { | |||||
| CreateQueueRequest, | CreateQueueRequest, | ||||
| CreateQueueResponse, | CreateQueueResponse, | ||||
| CreateRewardFundRequest, | CreateRewardFundRequest, | ||||
| EditQueueRequest, | |||||
| GetBalanceRequest, | GetBalanceRequest, | ||||
| GetBalanceResponse, | GetBalanceResponse, | ||||
| GetContributionsRequest, | GetContributionsRequest, | ||||
| @@ -19,6 +20,9 @@ import { | |||||
| GetRewardFundsRequest, | GetRewardFundsRequest, | ||||
| GetRewardFundsResponse, | GetRewardFundsResponse, | ||||
| LoginResponse, | LoginResponse, | ||||
| NearlyCompleteFundsRequest, | |||||
| NearlyCompleteFundsResponse, | |||||
| QueueMember, | |||||
| SuccessResponse, | SuccessResponse, | ||||
| } from '@/api/types'; | } from '@/api/types'; | ||||
| @@ -49,8 +53,7 @@ export const createRewardFund = ( | |||||
| issuerWallet: string, | issuerWallet: string, | ||||
| memo: string, | memo: string, | ||||
| minContribution: number, | minContribution: number, | ||||
| title: string, | |||||
| description: string, | |||||
| telegramLink: string, | |||||
| bonuses: Bonus[], | bonuses: Bonus[], | ||||
| queueID?: number | null | undefined, | queueID?: number | null | undefined, | ||||
| ) => controller.post<SuccessResponse, CreateRewardFundRequest>('CreateRewardFund', { | ) => controller.post<SuccessResponse, CreateRewardFundRequest>('CreateRewardFund', { | ||||
| @@ -60,8 +63,7 @@ export const createRewardFund = ( | |||||
| issuerWallet, | issuerWallet, | ||||
| memo, | memo, | ||||
| minContribution, | minContribution, | ||||
| title, | |||||
| description, | |||||
| telegramLink, | |||||
| bonuses, | bonuses, | ||||
| queueID, | queueID, | ||||
| }); | }); | ||||
| @@ -103,3 +105,10 @@ export const contribute = (privateKey: string, amount: number, rewardFund: numbe | |||||
| amount, | amount, | ||||
| rewardFund, | rewardFund, | ||||
| }); | }); | ||||
| export const getNearlyCompletedFunds = (threshold: number) => controller.post<NearlyCompleteFundsResponse, NearlyCompleteFundsRequest>('NearlyCompleteFunds', { threshold }); | |||||
| export const reorderQueue = (queueID: number, fundOrders: QueueMember[]) => controller.post<SuccessResponse, EditQueueRequest>('EditQueue', { | |||||
| queueID, | |||||
| fundOrders, | |||||
| }); | |||||
| @@ -28,8 +28,7 @@ export interface RewardFund { | |||||
| amountGoal: number; | amountGoal: number; | ||||
| minContribution: number; | minContribution: number; | ||||
| contributions: Contribution[] | null; | contributions: Contribution[] | null; | ||||
| title: string; | |||||
| description: string; | |||||
| telegramLink: string; | |||||
| } | } | ||||
| export interface Queue { | export interface Queue { | ||||
| @@ -37,6 +36,12 @@ export interface Queue { | |||||
| name: string; | name: string; | ||||
| } | } | ||||
| export interface QueueMember { | |||||
| id?: number; | |||||
| asset: string; | |||||
| order: number; | |||||
| } | |||||
| export interface CreateQueueRequest { | export interface CreateQueueRequest { | ||||
| name: string; | name: string; | ||||
| } | } | ||||
| @@ -70,8 +75,7 @@ export interface CreateRewardFundRequest { | |||||
| issuerWallet: string; | issuerWallet: string; | ||||
| memo: string; | memo: string; | ||||
| minContribution: number; | minContribution: number; | ||||
| title: string; | |||||
| description: string; | |||||
| telegramLink: string; | |||||
| queueID?: number | null; | queueID?: number | null; | ||||
| bonuses: Bonus[]; | bonuses: Bonus[]; | ||||
| } | } | ||||
| @@ -87,8 +91,7 @@ export interface FundInfo { | |||||
| amountAvailable: number; | amountAvailable: number; | ||||
| amountGoal: number; | amountGoal: number; | ||||
| minContribution: number; | minContribution: number; | ||||
| title: string; | |||||
| description: string; | |||||
| telegramLink: string; | |||||
| bonuses: Bonus[]; | bonuses: Bonus[]; | ||||
| queueID: number | null; | queueID: number | null; | ||||
| } | } | ||||
| @@ -149,6 +152,24 @@ export interface Claims { | |||||
| exp: number; | exp: number; | ||||
| } | } | ||||
| export interface NearlyCompletedFund { | |||||
| id: number; | |||||
| asset: string; | |||||
| minContribution: number; | |||||
| amountAvailable: number; | |||||
| memo: string; | |||||
| fundWallet: string; | |||||
| raised: number; | |||||
| } | |||||
| export interface NearlyCompleteFundsRequest { | |||||
| threshold: number; | |||||
| } | |||||
| export interface NearlyCompleteFundsResponse { | |||||
| funds: NearlyCompletedFund[]; | |||||
| } | |||||
| export interface GetContributionsRequest { | export interface GetContributionsRequest { | ||||
| id: number; | id: number; | ||||
| offset: number; | offset: number; | ||||
| @@ -162,3 +183,8 @@ export interface CloseRewardFundRequest { | |||||
| id: number; | id: number; | ||||
| close: boolean; | close: boolean; | ||||
| } | } | ||||
| export interface EditQueueRequest { | |||||
| queueID: number; | |||||
| fundOrders: QueueMember[]; | |||||
| } | |||||
| @@ -1,7 +1,18 @@ | |||||
| <template> | <template> | ||||
| <div class="is-flex is-flex-direction-row is-justify-content-space-between"> | |||||
| <div class="select mr-1"> | |||||
| <div | |||||
| class="is-flex is-flex-direction-row is-justify-content-space-between" | |||||
| :class="props.orientation === 'horizontal' | |||||
| ? 'is-flex-direction-row' | |||||
| : 'is-flex-direction-column'" | |||||
| > | |||||
| <div class="select" | |||||
| :class="props.orientation === 'horizontal' ? 'mr-1' : 'mr-1 mb-2'" | |||||
| :style="props.orientation === 'vertical' | |||||
| ? 'width: 28%; min-width: 180px; align-self: end' | |||||
| : undefined" | |||||
| > | |||||
| <select | <select | ||||
| style="width: 100%" | |||||
| ref="queueOptions" | ref="queueOptions" | ||||
| v-model="queueSelection" | v-model="queueSelection" | ||||
| aria-label="Queue Selection" | aria-label="Queue Selection" | ||||
| @@ -14,6 +25,12 @@ | |||||
| </option> | </option> | ||||
| </select> | </select> | ||||
| </div> | </div> | ||||
| <div v-if="queueSelection === undefined" class="is-flex-grow-1"> | |||||
| <div class="is-size-6 has-text-centered is-italic py-4"> | |||||
| Select an option from the menu | |||||
| {{ props.orientation === 'vertical' ? 'above' : 'to the left' }} | |||||
| </div> | |||||
| </div> | |||||
| <div v-if="queueSelection === -1" class="is-flex is-flex-direction-row is-flex-grow-1 ml-1"> | <div v-if="queueSelection === -1" class="is-flex is-flex-direction-row is-flex-grow-1 ml-1"> | ||||
| <input | <input | ||||
| v-model="queueName" | v-model="queueName" | ||||
| @@ -32,7 +49,7 @@ | |||||
| :key="element.order" | :key="element.order" | ||||
| > | > | ||||
| <div class="is-flex is-flex-direction-row is-justify-content-space-between"> | <div class="is-flex is-flex-direction-row is-justify-content-space-between"> | ||||
| <div>{{ element.title }} ({{ element.asset }})</div> | |||||
| <div>{{ element.asset }}</div> | |||||
| <div>{{ element.order }}</div> | <div>{{ element.order }}</div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -49,23 +66,22 @@ import { | |||||
| } from 'vue'; | } from 'vue'; | ||||
| import { | import { | ||||
| Queue, | Queue, | ||||
| QueueMember, | |||||
| RewardFund, | RewardFund, | ||||
| } from '@/api/types'; | } from '@/api/types'; | ||||
| import { | import { | ||||
| getQueueMembers, | getQueueMembers, | ||||
| getQueues, | getQueues, | ||||
| reorderQueue, | |||||
| } from '@/api/composed'; | } from '@/api/composed'; | ||||
| import { VueDraggableNext as Draggable } from 'vue-draggable-next'; | import { VueDraggableNext as Draggable } from 'vue-draggable-next'; | ||||
| interface QueueMember { | |||||
| id?: number; | |||||
| title: string; | |||||
| asset: string; | |||||
| order: number; | |||||
| } | |||||
| import { useDebounceFn } from '@vueuse/core'; | |||||
| // 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; }, | |||||
| orientation: 'horizontal' | 'vertical' | |||||
| }>(); | |||||
| // eslint-disable-next-line no-undef | // eslint-disable-next-line no-undef | ||||
| const emits = defineEmits(['selected', 'created']); | const emits = defineEmits(['selected', 'created']); | ||||
| @@ -75,13 +91,21 @@ const queueName = ref(undefined as string | undefined); | |||||
| const queueMembers = ref(undefined as QueueMember[] | undefined); | const queueMembers = ref(undefined as QueueMember[] | undefined); | ||||
| const serverQueues = ref(0); | const serverQueues = ref(0); | ||||
| const reorder = () => { | |||||
| const sendQueueOrder = useDebounceFn(async () => { | |||||
| if (queueSelection.value && queueMembers.value) { | |||||
| await reorderQueue(queueSelection.value, queueMembers.value); | |||||
| } | |||||
| }, 2000); | |||||
| const reorder = async () => { | |||||
| if (queueMembers.value) { | if (queueMembers.value) { | ||||
| for (let i = 0; i < queueMembers.value.length; i += 1) { | for (let i = 0; i < queueMembers.value.length; i += 1) { | ||||
| if (queueMembers.value[i]) { | if (queueMembers.value[i]) { | ||||
| queueMembers.value[i].order = (i + 1); | queueMembers.value[i].order = (i + 1); | ||||
| } | } | ||||
| } | } | ||||
| await sendQueueOrder(); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -107,16 +131,14 @@ const populateQueueMembers = async (id: number) => { | |||||
| const resp = await getQueueMembers(id) as { members: (RewardFund & { order: number; })[] }; | const resp = await getQueueMembers(id) as { members: (RewardFund & { order: number; })[] }; | ||||
| queueMembers.value = resp?.members.map((m) => ({ | queueMembers.value = resp?.members.map((m) => ({ | ||||
| id: m.id, | id: m.id, | ||||
| title: m.title, | |||||
| asset: m.asset, | asset: m.asset, | ||||
| order: m.order, | order: m.order, | ||||
| })); | })); | ||||
| serverQueues.value = queueMembers.value.length; | serverQueues.value = queueMembers.value.length; | ||||
| if (queueMembers.value && props.newMember.title && props.newMember.asset) { | |||||
| if (queueMembers.value && props.newMember.asset) { | |||||
| const newMember = { | const newMember = { | ||||
| id: undefined, | id: undefined, | ||||
| title: props.newMember.title, | |||||
| asset: props.newMember.asset, | asset: props.newMember.asset, | ||||
| order: queueMembers.value.length + 1, | order: queueMembers.value.length + 1, | ||||
| }; | }; | ||||
| @@ -134,10 +156,9 @@ 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.asset) { | |||||
| const assembleNewMember = (order: number) => ({ | const assembleNewMember = (order: number) => ({ | ||||
| id: undefined, | id: undefined, | ||||
| title: newVal.title, | |||||
| asset: newVal.asset, | asset: newVal.asset, | ||||
| order, | order, | ||||
| }); | }); | ||||
| @@ -1,8 +1,19 @@ | |||||
| <template> | <template> | ||||
| <div class="card py-2 px-4 has-text-dark" | <div class="card py-2 px-4 has-text-dark" | ||||
| :style="generateBackgroundStyle(`${fund.asset} ${fund.title}`)"> | :style="generateBackgroundStyle(`${fund.asset} ${fund.title}`)"> | ||||
| <div class="is-size-2-desktop is-size-2-tablet is-size-3-mobile"> | |||||
| {{ fund.asset }} | |||||
| <div class="is-flex | |||||
| is-flex-direction-row | |||||
| is-justify-content-space-between | |||||
| is-size-2-desktop | |||||
| is-size-2-tablet | |||||
| is-size-3-mobile" | |||||
| > | |||||
| <div> | |||||
| {{ fund.asset }} | |||||
| </div> | |||||
| <div v-if="props.aside"> | |||||
| {{ props.aside }} | |||||
| </div> | |||||
| </div> | </div> | ||||
| <div> | <div> | ||||
| <ul class="is-flex is-flex-direction-row is-justify-content-space-between"> | <ul class="is-flex is-flex-direction-row is-justify-content-space-between"> | ||||
| @@ -30,15 +41,18 @@ | |||||
| </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'; | ||||
| // 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>, | |||||
| aside: Object as PropType<string | number | undefined>, | |||||
| }); | |||||
| 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); | ||||
| @@ -14,6 +14,9 @@ import FundView from '@/views/FundView.vue'; | |||||
| import AddFundView from '@/views/AddFundView.vue'; | import AddFundView from '@/views/AddFundView.vue'; | ||||
| import hasPermission from '@/lib/auth'; | import hasPermission from '@/lib/auth'; | ||||
| import SignetRequestController from '@/api/requests'; | import SignetRequestController from '@/api/requests'; | ||||
| import AdminView from '@/views/AdminView.vue'; | |||||
| import ModifyQueueView from '@/views/ModifyQueueView.vue'; | |||||
| import AdminDashboardView from '@/views/AdminDashboardView.vue'; | |||||
| const routes: Array<RouteRecordRaw> = [ | const routes: Array<RouteRecordRaw> = [ | ||||
| { | { | ||||
| @@ -49,12 +52,60 @@ const routes: Array<RouteRecordRaw> = [ | |||||
| }, | }, | ||||
| }, | }, | ||||
| { | { | ||||
| path: '/addfund', | |||||
| name: 'addfund', | |||||
| component: AddFundView, | |||||
| path: '/admin', | |||||
| name: 'admin', | |||||
| component: AdminView, | |||||
| redirect: '/admin/dashboard', | |||||
| children: [ | |||||
| { | |||||
| path: 'dashboard', | |||||
| name: 'admindashboard', | |||||
| component: AdminDashboardView, | |||||
| meta: { | |||||
| requiredRights: Privileges.Admin, | |||||
| title: 'Admin', | |||||
| }, | |||||
| }, | |||||
| { | |||||
| path: 'addfund', | |||||
| name: 'addfund', | |||||
| component: AddFundView, | |||||
| meta: { | |||||
| requiredRights: Privileges.Admin, | |||||
| title: 'Add Group Fund', | |||||
| }, | |||||
| }, | |||||
| { | |||||
| path: 'modifyfund', | |||||
| name: 'modifyfund', | |||||
| component: AddFundView, | |||||
| meta: { | |||||
| requiredRights: Privileges.Admin, | |||||
| title: 'Add Group Fund', | |||||
| }, | |||||
| }, | |||||
| { | |||||
| path: 'addqueue', | |||||
| name: 'addqueue', | |||||
| component: AddFundView, | |||||
| meta: { | |||||
| requiredRights: Privileges.Admin, | |||||
| title: 'Add Group Fund', | |||||
| }, | |||||
| }, | |||||
| { | |||||
| path: 'modifyqueue', | |||||
| name: 'modifyqueue', | |||||
| component: ModifyQueueView, | |||||
| meta: { | |||||
| requiredRights: Privileges.Admin, | |||||
| title: 'Add Group Fund', | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| meta: { | meta: { | ||||
| requiredRights: Privileges.Admin, | requiredRights: Privileges.Admin, | ||||
| title: 'Add Group Fund', | |||||
| title: 'Administrator', | |||||
| }, | }, | ||||
| }, | }, | ||||
| ]; | ]; | ||||
| @@ -49,6 +49,7 @@ | |||||
| <div class="title is-5 has-text-white-ter">Queue</div> | <div class="title is-5 has-text-white-ter">Queue</div> | ||||
| <EditQueue | <EditQueue | ||||
| :new-member="constructFund()" | :new-member="constructFund()" | ||||
| orientation="horizontal" | |||||
| @created="setQueueName" | @created="setQueueName" | ||||
| @selected="setQueueSelection" | @selected="setQueueSelection" | ||||
| /> | /> | ||||
| @@ -0,0 +1,39 @@ | |||||
| <template> | |||||
| <div class="container is-max-desktop"> | |||||
| <section class="section is-small px-0"> | |||||
| <template v-if="nearlyCompletedFunds.length > 0"> | |||||
| <div class="title is-4 has-text-white-ter has-text-centered">Nearly Completed Funds</div> | |||||
| <div v-for="(fund, ind) in nearlyCompletedFunds" :key="ind"> | |||||
| <RouterLink :to="`/fund/${fund.id}`"> | |||||
| <FundLink :fund="fund" :aside="`${round(fund.raised/fund.amountAvailable*100)}%`"/> | |||||
| </RouterLink> | |||||
| </div> | |||||
| </template> | |||||
| </section> | |||||
| </div> | |||||
| </template> | |||||
| <script setup lang="ts"> | |||||
| import { ref } from 'vue'; | |||||
| import { getNearlyCompletedFunds } from '@/api/composed'; | |||||
| import FundLink from '@/components/FundLink.vue'; | |||||
| import { NearlyCompletedFund } from '@/api/types'; | |||||
| const nearlyCompletedFunds = ref([] as NearlyCompletedFund[]); | |||||
| const pctThreshold = 85; | |||||
| const req = await getNearlyCompletedFunds(pctThreshold); | |||||
| if (req?.funds) { | |||||
| nearlyCompletedFunds.value = req?.funds; | |||||
| } | |||||
| const round = (float: number, digits = 1) => { | |||||
| const factor = 10 ** digits; | |||||
| return Math.round(float * factor) / factor; | |||||
| }; | |||||
| </script> | |||||
| <style scoped lang="stylus"> | |||||
| </style> | |||||
| @@ -1,15 +1,17 @@ | |||||
| <template> | <template> | ||||
| <!-- Unused --> | <!-- Unused --> | ||||
| <div class="is-flex is-flex-direction-row"> | <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"> | |||||
| <span class="has-text-white has-text-weight-bold my-4 mx-2">Administration</span> | |||||
| <nav class="is-hidden-tablet-only is-hidden-mobile"> | |||||
| <div class="mt-6"> | |||||
| <div> | |||||
| <span class="has-text-white has-text-weight-bold my-4 mx-2">Administration</span> | |||||
| </div> | |||||
| <ul class="p-2"> | |||||
| <li v-for="(link, i) in links" v-bind:key="i"> | |||||
| <RouterLink :to="link.to" class="has-text-grey-light">{{ link.text }}</RouterLink> | |||||
| </li> | |||||
| </ul> | |||||
| </div> | </div> | ||||
| <ul class="p-2"> | |||||
| <li v-for="(link, i) in links" v-bind:key="i"> | |||||
| <RouterLink :to="link.to">{{ link.text }}</RouterLink> | |||||
| </li> | |||||
| </ul> | |||||
| </nav> | </nav> | ||||
| <div class="container is-max-desktop"> | <div class="container is-max-desktop"> | ||||
| <RouterView></RouterView> | <RouterView></RouterView> | ||||
| @@ -19,16 +21,30 @@ | |||||
| <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: 'Dashboard', | |||||
| to: '/admin/dashboard', | |||||
| }, | |||||
| { | |||||
| text: 'Add Fund', | |||||
| to: '/admin/addfund', | |||||
| }, | |||||
| { | |||||
| text: 'Modify Fund', | |||||
| to: '/admin/modifyfund', | |||||
| }, | |||||
| { | |||||
| text: 'Add/Modify Queue', | |||||
| to: '/admin/modifyqueue', | |||||
| }, | |||||
| ]; | ]; | ||||
| </script> | </script> | ||||
| <style scoped lang="stylus"> | <style scoped lang="stylus"> | ||||
| nav | nav | ||||
| min-width 134px | min-width 134px | ||||
| min-height 100vh | |||||
| height calc(100vh - 56px) | |||||
| li | li | ||||
| font-variant all-petite-caps | font-variant all-petite-caps | ||||
| @@ -1,16 +1,19 @@ | |||||
| <template> | <template> | ||||
| <div class="container is-max-desktop pb-4"> | <div class="container is-max-desktop pb-4"> | ||||
| <section class="section is-small"> | <section class="section is-small"> | ||||
| <div class="title is-size-4 has-text-white-ter has-text-centered"> | |||||
| {{ fund.fundInfo.title }} | |||||
| </div> | |||||
| <div | <div | ||||
| class="is-block-mobile | class="is-block-mobile | ||||
| is-flex-tablet-only | is-flex-tablet-only | ||||
| is-flex-desktop | is-flex-desktop | ||||
| is-flex-direction-row | is-flex-direction-row | ||||
| is-justify-content-space-between"> | is-justify-content-space-between"> | ||||
| <div class="fund-description pr-5" v-html="fixNewlines(fund.fundInfo.description)"> | |||||
| <div class="my-auto"> | |||||
| <div class="is-size-1">{{ fund.fundInfo.asset }}</div> | |||||
| <div> | |||||
| <a :href="fund.fundInfo.telegramLink" target="_blank" class="has-text-grey-light"> | |||||
| {{ fund.fundInfo.telegramLink }} | |||||
| </a> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <div | <div | ||||
| class="fund-details is-flex is-flex-direction-row is-justify-content-end my-auto py-6"> | class="fund-details is-flex is-flex-direction-row is-justify-content-end my-auto py-6"> | ||||
| @@ -375,7 +378,7 @@ const errs: SignetError[] = [ | |||||
| }, | }, | ||||
| ]; | ]; | ||||
| document.title = `Beignet - ${fund.value.fundInfo.title}`; | |||||
| document.title = `Beignet - ${fund.value.fundInfo.asset}`; | |||||
| watch(selectedDate, async (newVal) => { | watch(selectedDate, async (newVal) => { | ||||
| offset.value = 0; | offset.value = 0; | ||||
| @@ -0,0 +1,24 @@ | |||||
| <template> | |||||
| <div class="container is-max-desktop"> | |||||
| <section class="section is-small"> | |||||
| <div class="title is-4 has-text-white-ter has-text-centered"> | |||||
| Add/Modify Queue | |||||
| </div> | |||||
| <section class="section px-0 py-4"> | |||||
| <EditQueue :new-member="undefined" orientation="vertical" @created="createQueue"/> | |||||
| </section> | |||||
| </section> | |||||
| </div> | |||||
| </template> | |||||
| <script setup lang="ts"> | |||||
| import EditQueue from '@/components/EditQueue.vue'; | |||||
| import { createQueue } from '@/api/composed'; | |||||
| // | |||||
| </script> | |||||
| <style scoped lang="stylus"> | |||||
| </style> | |||||