AdminGuildsPage.vue 2.61 KB
<script setup>
import { onMounted, reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { Button, Card, Input } from '@drama/ui'

import { api } from '../api.js'

const { t } = useI18n()
const guilds = ref(null)
const forms = reactive({})
const error = ref('')

async function load() {
  guilds.value = (await api('GET', '/api/voko/admin/guilds')).guilds
  for (const guild of guilds.value) {
    if (forms[guild.id] === undefined) forms[guild.id] = { amount: '', note: '', goal: String(guild.weekly_goal), key: crypto.randomUUID() }
  }
}

/** @param {() => Promise<void>} action */
async function run(action) {
  error.value = ''
  try {
    await action()
    await load()
  } catch (err) {
    error.value = err instanceof Error ? err.message : String(err)
  }
}

/** @param {string} id */
const grant = (id) => run(async () => {
  const form = forms[id]
  await api('POST', `/api/voko/admin/guilds/${id}/budget`, { amount: Number(form.amount), note: form.note }, form.key)
  Object.assign(form, { amount: '', note: '', key: crypto.randomUUID() })
})

/** @param {string} id */
const saveGoal = (id) => run(() => api('PUT', `/api/voko/admin/guilds/${id}/weekly-goal`, { weekly_goal: Number(forms[id].goal) }))

onMounted(() => run(async () => {}))
</script>

<template>
  <h1>{{ t('adminGuilds.title') }}</h1>
  <p><router-link to="/admin">{{ t('adminNav.back') }}</router-link></p>
  <p v-if="error" role="alert">{{ error }}</p>
  <template v-if="guilds">
    <Card v-for="guild in guilds" :key="guild.id" class="voko-card">
      <h2>{{ guild.name }} · {{ t('world.guildLevel', { level: guild.level }) }}</h2>
      <p>{{ t('adminGuilds.lead', { email: guild.lead_email }) }}</p>
      <template v-if="guild.budget">
        <p>{{ t('adminGuilds.company', { name: guild.company_agent_name }) }} · {{ t('agents.wallet', guild.budget) }}</p>
        <label class="voko-field">{{ t('adminGuilds.amount') }}<Input v-model="forms[guild.id].amount" type="number" /></label>
        <label class="voko-field">{{ t('adminGuilds.note') }}<Input v-model="forms[guild.id].note" /></label>
        <Button :disabled="forms[guild.id].amount === '' || forms[guild.id].note.trim() === ''" @click="grant(guild.id)">{{ t('adminGuilds.grant') }}</Button>
      </template>
      <p v-else>{{ t('adminGuilds.noCompany') }}</p>
      <label class="voko-field">{{ t('adminGuilds.goal') }}<Input v-model="forms[guild.id].goal" type="number" /></label>
      <Button variant="secondary" @click="saveGoal(guild.id)">{{ t('adminGuilds.saveGoal') }}</Button>
    </Card>
  </template>
</template>

<style scoped>
.voko-card {
  margin-bottom: var(--drama-space-md);
}
</style>