peregrine/web/src/stores/settings/license.ts
pyr0ball 8bd1be7b16 feat(web): merge Vue SPA from feature/vue-spa; add ClassicUIButton + useFeatureFlag
- Import web/ directory (Vue 3 + Vite + UnoCSS SPA) from feature/vue-spa branch
- Add web/src/components/ClassicUIButton.vue: switch-back to Streamlit via
  cookie (prgn_ui=streamlit) + ?prgn_switch=streamlit query param bridge
- Add web/src/composables/useFeatureFlag.ts: reads prgn_demo_tier cookie for
  demo toolbar visual consistency (not an authoritative gate, see issue #8)
- Update .gitignore: add .superpowers/, pytest-output.txt, docs/superpowers/
2026-03-22 18:46:11 -07:00

51 lines
1.8 KiB
TypeScript

import { ref } from 'vue'
import { defineStore } from 'pinia'
import { useApiFetch } from '../../composables/useApi'
export const useLicenseStore = defineStore('settings/license', () => {
const tier = ref<string>('free')
const licenseKey = ref<string | null>(null)
const active = ref(false)
const gracePeriodEnds = ref<string | null>(null)
const loading = ref(false)
const activating = ref(false)
const activateError = ref<string | null>(null)
async function loadLicense() {
loading.value = true
const { data } = await useApiFetch<{tier: string; key: string | null; active: boolean; grace_period_ends?: string}>('/api/settings/license')
loading.value = false
if (!data) return
tier.value = data.tier
licenseKey.value = data.key
active.value = data.active
gracePeriodEnds.value = data.grace_period_ends ?? null
}
async function activate(key: string) {
activating.value = true
activateError.value = null
const { data } = await useApiFetch<{ok: boolean; tier?: string; error?: string}>(
'/api/settings/license/activate',
{ method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key }) }
)
activating.value = false
if (!data) { activateError.value = 'Request failed'; return }
if (data.ok) {
active.value = true
tier.value = data.tier ?? tier.value
licenseKey.value = key
} else {
activateError.value = data.error ?? 'Activation failed'
}
}
async function deactivate() {
await useApiFetch('/api/settings/license/deactivate', { method: 'POST' })
active.value = false
licenseKey.value = null
tier.value = 'free'
}
return { tier, licenseKey, active, gracePeriodEnds, loading, activating, activateError, loadLicense, activate, deactivate }
})