- 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/
42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
import { ref } from 'vue'
|
|
import { defineStore } from 'pinia'
|
|
import { useApiFetch } from '../composables/useApi'
|
|
|
|
export type Tier = 'free' | 'paid' | 'premium' | 'ultra'
|
|
export type InferenceProfile = 'remote' | 'cpu' | 'single-gpu' | 'dual-gpu'
|
|
|
|
export const useAppConfigStore = defineStore('appConfig', () => {
|
|
const isCloud = ref(false)
|
|
const isDevMode = ref(false)
|
|
const tier = ref<Tier>('free')
|
|
const contractedClient = ref(false)
|
|
const inferenceProfile = ref<InferenceProfile>('cpu')
|
|
const loaded = ref(false)
|
|
const devTierOverride = ref(localStorage.getItem('dev_tier_override') ?? '')
|
|
|
|
async function load() {
|
|
const { data } = await useApiFetch<{
|
|
isCloud: boolean; isDevMode: boolean; tier: Tier
|
|
contractedClient: boolean; inferenceProfile: InferenceProfile
|
|
}>('/api/config/app')
|
|
if (!data) return
|
|
isCloud.value = data.isCloud
|
|
isDevMode.value = data.isDevMode
|
|
tier.value = data.tier
|
|
contractedClient.value = data.contractedClient
|
|
inferenceProfile.value = data.inferenceProfile
|
|
loaded.value = true
|
|
}
|
|
|
|
function setDevTierOverride(value: string | null) {
|
|
if (value) {
|
|
localStorage.setItem('dev_tier_override', value)
|
|
devTierOverride.value = value
|
|
} else {
|
|
localStorage.removeItem('dev_tier_override')
|
|
devTierOverride.value = ''
|
|
}
|
|
}
|
|
|
|
return { isCloud, isDevMode, tier, contractedClient, inferenceProfile, loaded, load, devTierOverride, setDevTierOverride }
|
|
})
|