webapp/vite.config.ts
Padreug 2cc8e34b9d feat(layout): re-enable "Back to hub" with a sticky sheet footer
Reverses the events-only hide (c037d45) now that the link has a real
home. Three parts:

- Add a @brand-hub-logo alias (brandHubLogoAliasEntry) resolving to the
  brand's primary/global logo — the HUB's logo, never the per-standalone
  @brand-app-logo. Wired into all 9 app vite configs since the shared
  ProfileSheetContent renders it.
- Restructure the profile sheet into a fixed-height flex column: a
  flex-1 min-h-0 overflow-y-auto scroll region over a shrink-0 footer,
  so "Back to hub" + the log-in/out bar stay pinned to the bottom while
  the identity/preferences area scrolls.
- Move the edit-profile Dialog out of the flex root (it portals to body,
  so it's not part of the sheet flow).

Logo bumped to w-8 h-8, centered, with tightened footer padding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 00:26:52 +02:00

73 lines
2.2 KiB
TypeScript

import { fileURLToPath, URL } from 'node:url'
import vue from '@vitejs/plugin-vue'
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'vite'
import Inspect from 'vite-plugin-inspect'
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer'
import { visualizer } from 'rollup-plugin-visualizer'
import { brand, brandAlias, brandAppLogoAliasEntry, brandAssetsPlugin, brandHubLogoAliasEntry } from './vite-branding'
// https://vite.dev/config/
//
// The hub is intentionally NOT a PWA (closes #41). Its scope `/` claimed
// the entire origin and blocked Chrome from offering installs for the
// path-mounted standalones at /libra/, /market/, etc. The hub is a
// launcher page; users install the standalones they actually use.
// Brand name flows into index.html's `%VITE_APP_NAME% Hub` title via
// Vite's HTML env-var substitution.
process.env.VITE_APP_NAME = brand.name
export default defineConfig(({ mode }) => ({
// Per-app dep cache so concurrent dev servers don't race on .vite/deps
cacheDir: 'node_modules/.vite-hub',
server: {
port: 5173,
strictPort: true,
},
plugins: [
brandAssetsPlugin(),
vue(),
tailwindcss(),
Inspect(),
ViteImageOptimizer({
jpg: {
quality: 80
},
png: {
quality: 80
},
webp: {
lossless: true
}
}),
mode === 'analyze' && visualizer({
open: true,
filename: 'dist/stats.html',
gzipSize: true,
brotliSize: true
})
],
resolve: {
// Array form so the per-standalone logo regex (matches `@brand-app-logo`
// with optional `?url` query) doesn't get shadowed by the bare alias.
alias: [
brandAppLogoAliasEntry(),
brandHubLogoAliasEntry(),
...Object.entries(brandAlias).map(([find, replacement]) => ({ find, replacement })),
{ find: '@', replacement: fileURLToPath(new URL('./src', import.meta.url)) },
]
},
build: {
rollupOptions: {
output: {
manualChunks: {
'vue-vendor': ['vue', 'vue-router', 'pinia'],
'ui-vendor': ['radix-vue', '@vueuse/core'],
'shadcn': ['class-variance-authority', 'clsx', 'tailwind-merge']
}
}
},
chunkSizeWarningLimit: 1000
}
}))