a
File size: 3,491 Bytes
6c38a8d
 
 
 
f0e0245
0c21886
 
6c38a8d
5cc036a
6c38a8d
 
 
 
 
 
0c21886
6c38a8d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0c21886
6c38a8d
 
 
0c21886
6c38a8d
 
 
 
 
 
 
 
 
f0e0245
6c38a8d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
edf424c
c6cd789
6c38a8d
 
 
 
 
 
ed3fb12
6c38a8d
5cc036a
 
 
 
 
 
6c38a8d
 
 
 
 
 
 
0c21886
6c38a8d
 
 
 
 
f4003d6
a5bc115
 
76b8a0b
6c38a8d
 
 
edf424c
6c38a8d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import { selfApi, type SaveSettingsPayload } from '@/lib/api'
import RenderSettingsForm from '@/components/RenderSettingsForm.vue'
import type { RenderSettings } from '@/components/RenderSettingsForm.vue'
import { Button } from '@/components/ui/button'
import { BookOpen } from 'lucide-vue-next'

const auth = useAuthStore()
const router = useRouter()

const keyName = ref('')
const keyPrefix = ref('')
const settings = ref<RenderSettings | null>(null)
const settingsLoading = ref(true)
const initError = ref('')

onMounted(async () => {
  try {
    const [infoRes, settingsRes] = await Promise.all([
      selfApi.getInfo(),
      selfApi.getSettings(),
    ])

    if (!infoRes.ok || !settingsRes.ok) {
      auth.logoutApiKey()
      router.replace('/login')
      return
    }

    const info = await infoRes.json()
    keyName.value = info.name
    keyPrefix.value = info.key_prefix
    auth.apiKeyInfo = { name: info.name, key_prefix: info.key_prefix }

    settings.value = await settingsRes.json()
  } catch {
    initError.value = 'Failed to load settings'
  } finally {
    settingsLoading.value = false
  }
})

async function loadSettings(): Promise<RenderSettings | null> {
  try {
    const res = await selfApi.getSettings()
    if (res.ok) {
      const data: RenderSettings = await res.json()
      settings.value = data
      return data
    }
  } catch {
    // handled by form
  }
  return null
}

async function saveSettings(s: SaveSettingsPayload): Promise<string | null> {
  const res = await selfApi.updateSettings(s)
  if (res.ok) return null
  const data = await res.json().catch(() => null)
  return data?.error || 'Failed to save'
}

async function resetSettings(): Promise<boolean> {
  const res = await selfApi.resetSettings()
  return res.ok
}

function handleLogout() {
  auth.logoutApiKey()
  router.push('/login')
}
</script>

<template>
  <main class="min-h-screen flex items-center justify-center">
    <div class="w-full max-w-6xl space-y-6">
      <div class="flex items-center justify-between">
        <div>
          <p v-if="keyName" class="text-sm text-muted-foreground">
            {{ keyName }}
            <span class="font-mono">({{ keyPrefix }}...)</span>
          </p>
          <h1 class="text-2xl font-normal">Image Settings</h1>
        </div>
        <Button v-if="auth.disablePublicPages" as-child variant="outline" size="sm">
          <router-link to="/docs">
            <BookOpen class="h-4 w-4" />
            API Docs
          </router-link>
        </Button>
        <Button variant="outline" size="sm" @click="handleLogout">Logout</Button>
      </div>

      <div v-if="settingsLoading" class="text-sm text-muted-foreground">Loading settings...</div>
      <div v-else-if="initError" class="text-sm text-destructive">{{ initError }}</div>

      <div v-else-if="settings" class="rounded-md border p-4">
        <RenderSettingsForm
          :settings="settings"
          uid="self"
          :load-settings="loadSettings"
          :save-settings="saveSettings"
          :reset-settings="resetSettings"
          :fetch-preview="selfApi.previewPoster"
          :fetch-logo-preview="selfApi.previewLogo"
          :fetch-backdrop-preview="selfApi.previewBackdrop"
          :fetch-episode-preview="selfApi.previewEpisode"
        />
      </div>
    </div>
  </main>
</template>