From 2c7ab2b73429305c2592b96ffb976fdbd5c4f636 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Mon, 9 Feb 2026 02:46:30 -0800 Subject: [PATCH] Use i18n for board component strings, show controls in edit mode, require website before editing - Replace raw strings with useMessages hook in BoardColumn and BoardComponentSelect - Show WebsiteControls on edit screen so users can test filters - Disable board body editing until a website is selected - Scope website select to team websites when editing a team board Co-Authored-By: Claude Opus 4.6 --- public/intl/messages/en-US.json | 3 +++ src/app/(main)/boards/[boardId]/BoardBody.tsx | 6 +++-- .../(main)/boards/[boardId]/BoardColumn.tsx | 5 ++-- .../boards/[boardId]/BoardComponentSelect.tsx | 24 +++++++------------ src/app/(main)/boards/[boardId]/BoardPage.tsx | 4 ++-- src/components/messages.ts | 3 +++ 6 files changed, 23 insertions(+), 22 deletions(-) diff --git a/public/intl/messages/en-US.json b/public/intl/messages/en-US.json index 5fe797d85..3fdffef66 100644 --- a/public/intl/messages/en-US.json +++ b/public/intl/messages/en-US.json @@ -255,6 +255,7 @@ "select-date": "Select date", "select-filter": "Select filter", "select-role": "Select role", + "select-component": "Select component", "select-website": "Select website", "session": "Session", "session-data": "Session data", @@ -371,6 +372,8 @@ "reset-website": "To reset this website, type {confirmation} in the box below to confirm.", "reset-website-warning": "All statistics for this website will be deleted, but your settings will remain intact.", "saved": "Saved.", + "select-component-preview": "Select a component to preview", + "select-website-first": "Select a website first", "sever-error": "Server error", "share-url": "Your website stats are publicly available at the following URL:", "team-already-member": "You are already a member of the team.", diff --git a/src/app/(main)/boards/[boardId]/BoardBody.tsx b/src/app/(main)/boards/[boardId]/BoardBody.tsx index 5e2c32264..e3c363cb3 100644 --- a/src/app/(main)/boards/[boardId]/BoardBody.tsx +++ b/src/app/(main)/boards/[boardId]/BoardBody.tsx @@ -103,6 +103,8 @@ export function BoardBody() { }); }; + const websiteId = board?.parameters?.websiteId; + const canEdit = editing && !!websiteId; const rows = board?.parameters?.rows ?? []; const minHeight = (rows?.length || 1) * MAX_ROW_HEIGHT + BUTTON_ROW_HEIGHT; @@ -121,7 +123,7 @@ export function BoardBody() { rowId={row.id} rowIndex={index} rowCount={rows?.length} - editing={editing} + editing={canEdit} onRemove={handleRemoveRow} onMoveUp={handleMoveRowUp} onMoveDown={handleMoveRowDown} @@ -131,7 +133,7 @@ export function BoardBody() { {index < rows?.length - 1 && } ))} - {editing && ( + {canEdit && ( diff --git a/src/app/(main)/boards/[boardId]/BoardColumn.tsx b/src/app/(main)/boards/[boardId]/BoardColumn.tsx index 4cffe00b6..8be9c02da 100644 --- a/src/app/(main)/boards/[boardId]/BoardColumn.tsx +++ b/src/app/(main)/boards/[boardId]/BoardColumn.tsx @@ -9,7 +9,7 @@ import { TooltipTrigger, } from '@umami/react-zen'; import { useState } from 'react'; -import { useBoard } from '@/components/hooks'; +import { useBoard, useMessages } from '@/components/hooks'; import { Pencil, Plus, X } from '@/components/icons'; import type { BoardComponentConfig } from '@/lib/types'; import { BoardComponentRenderer } from './BoardComponentRenderer'; @@ -32,6 +32,7 @@ export function BoardColumn({ }) { const [showSelect, setShowSelect] = useState(false); const { board } = useBoard(); + const { t, labels } = useMessages(); const websiteId = board?.parameters?.websiteId; const handleSelect = (config: BoardComponentConfig) => { @@ -91,7 +92,7 @@ export function BoardColumn({ )} void; onClose: () => void; }) { + const { t, labels, messages } = useMessages(); const [selectedDef, setSelectedDef] = useState(null); const [configValues, setConfigValues] = useState>({}); @@ -79,13 +71,13 @@ export function BoardComponentSelect({ return ( - + {CATEGORIES.map(cat => { const components = getComponentsByCategory(cat.key); return ( - {cat.name} + {cat.name} {components.map(def => ( - {websiteId ? 'Select a component to preview' : 'Select a website first'} + {websiteId ? t(messages.selectComponentPreview) : t(messages.selectWebsiteFirst)} )} @@ -164,10 +156,10 @@ export function BoardComponentSelect({ diff --git a/src/app/(main)/boards/[boardId]/BoardPage.tsx b/src/app/(main)/boards/[boardId]/BoardPage.tsx index f8b78d6f0..96b1cf865 100644 --- a/src/app/(main)/boards/[boardId]/BoardPage.tsx +++ b/src/app/(main)/boards/[boardId]/BoardPage.tsx @@ -22,10 +22,10 @@ export function BoardPage({ boardId, editing = false }: { boardId?: string; edit } function BoardControls() { - const { board, editing } = useBoard(); + const { board } = useBoard(); const websiteId = board?.parameters?.websiteId; - if (editing || !websiteId) { + if (!websiteId) { return null; } diff --git a/src/components/messages.ts b/src/components/messages.ts index e93cb8f81..955324ba6 100644 --- a/src/components/messages.ts +++ b/src/components/messages.ts @@ -309,6 +309,7 @@ export const labels: Record = { pixel: 'label.pixel', pixels: 'label.pixels', addBoard: 'label.add-board', + selectComponent: 'label.select-component', addLink: 'label.add-link', addPixel: 'label.add-pixel', maximize: 'label.maximize', @@ -367,6 +368,8 @@ export const messages: Record = { noResultsFound: 'message.no-results-found', noWebsitesConfigured: 'message.no-websites-configured', noTeamWebsites: 'message.no-team-websites', + selectComponentPreview: 'message.select-component-preview', + selectWebsiteFirst: 'message.select-website-first', teamWebsitesInfo: 'message.team-websites-info', noMatchPassword: 'message.no-match-password', goToSettings: 'message.go-to-settings',