feat(panel): Beta sweep — multi-game coherence, honesty, UX fixes
All checks were successful
CI / backend-types (push) Successful in 10s
CI / frontend-build (push) Successful in 15s
CI / agent-tests (push) Successful in 45s
CI / integration (push) Successful in 22s

Multi-game rebrand (no more Rust-only leftovers): game-neutral setup wizard +
deploy/store defaults; player-id labels driven by game profile (Steam ID only
for Rust); blueprint wipe type + verify-plugins gated to uMod games; oxide
command examples + Rust-only plugin pages (AutoDoors/FurnaceSplitter/BetterChat)
guarded behind mods==='umod' with empty-states for other games.

Honesty: webstore checkout shows coming-soon (backend now 503s); 'integrated
webstore' marketed as coming-soon; Discord references neutralized to
community/webhook; migration FAQ marked in-development; analytics dev phase
labels removed; Network pricing tier set to Custom/Contact (was a confusing
duplicate of Operator); docs/PRICING.md rewritten to match live subscriptions.

UX/bugs: fixed ServerView oxide-status operator-precedence bug; dead 'Deploy
server' button wired; non-functional topbar search removed; alert()/confirm()
replaced with toasts across schedules/alerts/migration/public store+server;
analytics chart arrays null-guarded; production console.logs gated to DEV.

Frontend build (vue-tsc + vite) green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Vantz Stockwell
2026-06-11 22:06:10 -04:00
parent f2ea415840
commit 6f783bfac8
28 changed files with 265 additions and 99 deletions

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { useToastStore } from '@/stores/toast'
import type { PublicStoreInfo, PublicStoreItem, StorePurchaseRequest, StorePurchaseResponse } from '@/types'
import { safeCurrency } from '@/utils/formatters'
import Panel from '@/components/ds/data/Panel.vue'
@@ -15,6 +16,7 @@ import Logo from '@/components/ds/brand/Logo.vue'
const route = useRoute()
const subdomain = computed(() => route.params.subdomain as string)
const toast = useToastStore()
const isLoading = ref(false)
const storeInfo = ref<PublicStoreInfo | null>(null)
@@ -125,6 +127,12 @@ async function confirmPurchase() {
body: JSON.stringify(payload)
})
if (response.status === 503) {
closePurchaseModal()
toast.info("Checkout is coming soon — payments aren't enabled yet.")
return
}
if (!response.ok) {
const error = await response.json().catch(() => ({ message: 'Purchase failed' }))
throw new Error(error.message || 'Purchase failed')
@@ -137,8 +145,7 @@ async function confirmPurchase() {
// Close modal and show success message
closePurchaseModal()
// TODO: Show toast notification
alert('PayPal window opened. Complete your payment there. Your items will be delivered automatically after payment.')
toast.success('PayPal window opened. Complete your payment there. Your items will be delivered automatically after payment.')
} catch (error: any) {
purchaseError.value = error.message || 'Purchase failed. Please try again.'
} finally {