mirror of
https://github.com/luxfi/work-board.git
synced 2026-07-28 22:28:51 +00:00
fix: green the work-board build — decouple logo assets from brands.ts
- brands.ts was importing .svg logos at top level; vite.config.ts imports brands.ts (for build-time title/CSP), and the config bundler parses SVG markup as JSX → 'Unexpected JSX expression'. Split the .svg imports into a runtime-only src/brand-logos.ts (BRAND_LOGOS keyed by BrandKey); brands.ts is now pure, bundler-safe config data. ui.tsx BrandMark/BrandLogo read BRAND_LOGOS[BRAND_KEY]. - fixture.ts: add lux+hanzo empty fixtures (no live bounty yet) to satisfy Record<BrandKey,...> after brands.ts grew to 4 brands. Full build green (tsc + vite). Lands the in-flight ⌘K palette, 6-category symmetrical grid, real brand logos, and proper accents (Zoo #6c5efb indigo, Pars #1C3879 Persian blue, Lux #7000FF, Hanzo #ea580c — placeholder green gone). Co-authored-by: Hanzo Dev <dev@hanzo.ai>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import type { BrandKey } from './brands';
|
||||
|
||||
// Runtime-only brand logo assets. Kept SEPARATE from brands.ts on purpose:
|
||||
// vite.config.ts imports brands.ts (for the build-time <title> + CSP RPC host),
|
||||
// and the Vite config bundler can't process `.svg` imports — it parses the SVG
|
||||
// `<svg>` markup as JSX and fails. So brands.ts stays pure config data (bundler-
|
||||
// safe) and the .svg imports live here, imported only by the components that
|
||||
// render a logo. Vite inlines these small SVGs as `data:` URIs (under the 4 KB
|
||||
// limit), which the strict production CSP permits via `img-src 'self' data:`.
|
||||
// Each mark is the brand's own canonical asset — never cross-brand.
|
||||
import zooWordmark from './assets/brands/zoo/wordmark.svg';
|
||||
import parsWordmark from './assets/brands/pars/wordmark.svg';
|
||||
import parsMark from './assets/brands/pars/mark.svg';
|
||||
import luxWordmark from './assets/brands/lux/wordmark.svg';
|
||||
import luxMark from './assets/brands/lux/mark.svg';
|
||||
import hanzoWordmark from './assets/brands/hanzo/wordmark.svg';
|
||||
import hanzoMark from './assets/brands/hanzo/mark.svg';
|
||||
|
||||
export type BrandLogos = { logo: string; logoMark: string };
|
||||
|
||||
// logo = full wordmark; logoMark = square/icon mark. Zoo ships one trigram for both.
|
||||
export const BRAND_LOGOS: Record<BrandKey, BrandLogos> = {
|
||||
zoo: { logo: zooWordmark, logoMark: zooWordmark },
|
||||
pars: { logo: parsWordmark, logoMark: parsMark },
|
||||
lux: { logo: luxWordmark, logoMark: luxMark },
|
||||
hanzo: { logo: hanzoWordmark, logoMark: hanzoMark },
|
||||
};
|
||||
+3
-26
@@ -1,18 +1,7 @@
|
||||
import type { Address } from 'viem';
|
||||
|
||||
// Brand logos — embedded at build time. Vite inlines these small SVGs as `data:`
|
||||
// URIs (well under the 4 KB asset-inline limit), which the strict production CSP
|
||||
// permits via `img-src 'self' data:`; a missing file fails the build. Each mark is
|
||||
// the brand's own canonical asset (from its @<org>/brand package or app public/),
|
||||
// never cross-brand: a Zoo build embeds only Zoo. `logo` is the full wordmark,
|
||||
// `logoMark` the square/icon mark. Zoo ships one trigram that serves as both.
|
||||
import zooWordmark from './assets/brands/zoo/wordmark.svg';
|
||||
import parsWordmark from './assets/brands/pars/wordmark.svg';
|
||||
import parsMark from './assets/brands/pars/mark.svg';
|
||||
import luxWordmark from './assets/brands/lux/wordmark.svg';
|
||||
import luxMark from './assets/brands/lux/mark.svg';
|
||||
import hanzoWordmark from './assets/brands/hanzo/wordmark.svg';
|
||||
import hanzoMark from './assets/brands/hanzo/mark.svg';
|
||||
// NOTE: brand logo .svg imports live in ./brand-logos.ts, NOT here. vite.config.ts
|
||||
// imports this module for the build-time title/CSP, and the config bundler can't
|
||||
// parse .svg imports (it reads the SVG markup as JSX). Keep brands.ts asset-free.
|
||||
|
||||
// The one place a white-label lives. A brand is selected at BUILD time by the
|
||||
// VITE_BRAND build-arg (see Dockerfile / docker.yml); default is 'zoo'. Every
|
||||
@@ -60,10 +49,6 @@ export type Brand = {
|
||||
accent: string;
|
||||
// Optional secondary/highlight hex (e.g. Pars gold). Omit for single-accent brands.
|
||||
accentSecondary?: string;
|
||||
// Brand logos — embedded SVGs (imported → build-inlined `data:` URI string).
|
||||
// `logo` is the full wordmark; `logoMark` the square/icon mark. Never cross-brand.
|
||||
logo: string;
|
||||
logoMark: string;
|
||||
usdPerNative: number; // native → USD for the "Total paid: $X" header stat
|
||||
social: { discord?: string; twitter?: string; website?: string };
|
||||
tags: string[]; // About-panel chips
|
||||
@@ -94,8 +79,6 @@ export const BRANDS = {
|
||||
workspace: 'Zoo',
|
||||
tagline: 'Open AI research network — DeAI & DeSci',
|
||||
accent: '#6c5efb',
|
||||
logo: zooWordmark,
|
||||
logoMark: zooWordmark,
|
||||
usdPerNative: 1,
|
||||
social: { discord: 'https://discord.gg/zoo', twitter: 'https://twitter.com/zoo_labs', website: 'https://zoo.ngo' },
|
||||
tags: ['DeAI', 'DeSci', 'Research', 'Open Source', 'AI'],
|
||||
@@ -125,8 +108,6 @@ export const BRANDS = {
|
||||
tagline: 'The community L1',
|
||||
accent: '#1C3879',
|
||||
accentSecondary: '#D4AF37',
|
||||
logo: parsWordmark,
|
||||
logoMark: parsMark,
|
||||
usdPerNative: 1,
|
||||
social: { website: 'https://pars.network' },
|
||||
tags: ['Community', 'L1', 'Governance'],
|
||||
@@ -156,8 +137,6 @@ export const BRANDS = {
|
||||
workspace: 'Lux',
|
||||
tagline: 'Quantum-safe multi-consensus L1',
|
||||
accent: '#7000FF',
|
||||
logo: luxWordmark,
|
||||
logoMark: luxMark,
|
||||
usdPerNative: 1,
|
||||
social: { discord: 'https://discord.gg/lux', twitter: 'https://x.com/luxfi', website: 'https://lux.network' },
|
||||
tags: ['Consensus', 'Post-Quantum', 'L1', 'DeFi', 'Open Source'],
|
||||
@@ -187,8 +166,6 @@ export const BRANDS = {
|
||||
workspace: 'Hanzo',
|
||||
tagline: 'Frontier AI & foundational models',
|
||||
accent: '#ea580c',
|
||||
logo: hanzoWordmark,
|
||||
logoMark: hanzoMark,
|
||||
usdPerNative: 1,
|
||||
social: { discord: 'https://discord.gg/hanzo', website: 'https://hanzo.ai' },
|
||||
tags: ['AI', 'LLM', 'MCP', 'Agents', 'Open Source'],
|
||||
|
||||
@@ -51,6 +51,10 @@ const FIXTURES: Record<BrandKey, BountyView[]> = {
|
||||
reputation: { completed: 1n, earned: 200000000000000n },
|
||||
},
|
||||
],
|
||||
// lux + hanzo: work-market staged (not yet deployed) → no live bounty #0 to mirror.
|
||||
// Empty until their contracts land; the UI shows an empty board offline, not another chain's data.
|
||||
lux: [],
|
||||
hanzo: [],
|
||||
};
|
||||
|
||||
export const FIXTURE: BountyView[] = FIXTURES[BRAND_KEY];
|
||||
|
||||
+4
-3
@@ -4,7 +4,8 @@ import { skillMeta } from './skills';
|
||||
import { formatReward } from './reward';
|
||||
import type { NftMeta } from './reward';
|
||||
import type { Reward } from './types';
|
||||
import { NATIVE_SYMBOL, ORG } from './config';
|
||||
import { NATIVE_SYMBOL, ORG, BRAND_KEY } from './config';
|
||||
import { BRAND_LOGOS } from './brand-logos';
|
||||
|
||||
// ---- Brand accent ----
|
||||
export const accent: CSSProperties = { backgroundColor: 'var(--brand)' };
|
||||
@@ -17,7 +18,7 @@ export const accentText: CSSProperties = { color: 'var(--brand)' };
|
||||
// the logo fields defensively (optional) — ae530aa6 supplies them; until then the
|
||||
// letter tile / name stand in, and the image appears the moment the field lands.
|
||||
export function BrandMark({ size = 28, className = '' }: { size?: number; className?: string }) {
|
||||
const mark = (ORG as { logoMark?: string }).logoMark;
|
||||
const mark = BRAND_LOGOS[BRAND_KEY].logoMark;
|
||||
const radius = Math.round(size * 0.28);
|
||||
if (mark) {
|
||||
return (
|
||||
@@ -43,7 +44,7 @@ export function BrandMark({ size = 28, className = '' }: { size?: number; classN
|
||||
}
|
||||
|
||||
export function BrandLogo({ className = '' }: { className?: string }) {
|
||||
const logo = (ORG as { logo?: string }).logo;
|
||||
const logo = BRAND_LOGOS[BRAND_KEY].logo;
|
||||
return (
|
||||
<span className={`flex min-w-0 items-center gap-2.5 ${className}`}>
|
||||
{logo ? (
|
||||
|
||||
Reference in New Issue
Block a user