Rename Brain to Upload material and Instruction to Brain and AI

Upload material (/upload) drops the metric cards for a larger upload box
above the material list; Brain and AI moves to /brain. Old paths redirect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Iqbal
2026-10-27 22:36:52 +07:00
parent c1063bfa7e
commit ef4fb7d971
10 changed files with 43 additions and 40 deletions

View File

@@ -5,7 +5,7 @@ import {
type Source,
} from '../api/engine'
import { Icon } from '../components/Icon'
import { Empty, PageHead, Skeleton, SkeletonLines, SkeletonRows } from '../components/Page'
import { Empty, PageHead, SkeletonLines, SkeletonRows } from '../components/Page'
import { toast } from '../components/Toast'
import { locale, t } from '../i18n'
@@ -28,17 +28,10 @@ export function BrainPage() {
// Poll quickly while anything is processing or building; slowly otherwise (colleagues may upload too).
refetchInterval: q => (q.state.data?.some(d => phaseOf(d) === 'working') ? 3000 : 20_000),
})
const ready = docs.data?.filter(d => phaseOf(d) === 'ready').length ?? 0
const waiting = docs.data?.filter(d => phaseOf(d) === 'answer').length ?? 0
return (
<>
<PageHead title={t('brain.title')} description={t('brain.description')} />
<div className="metrics">
<div className="metric"><span>{t('brain.metricMaterial')}</span>{docs.data ? <strong>{docs.data.length}</strong> : <Skeleton className="skel-num" />}<small>{t('brain.metricMaterialSub')}</small></div>
<div className="metric"><span>{t('brain.metricReady')}</span>{docs.data ? <strong>{ready}</strong> : <Skeleton className="skel-num" />}<small>{t('brain.metricReadySub')}</small></div>
<div className="metric"><span>{t('brain.metricAction')}</span>{docs.data ? <strong>{waiting}</strong> : <Skeleton className="skel-num" />}<small>{t('brain.metricActionSub')}</small></div>
</div>
<UploadBox />
<div className="card">
<div className="card-head"><h3>{t('brain.listTitle')}</h3><Icon name="brain" /></div>
@@ -116,7 +109,7 @@ function UploadBox() {
const busy = items.some(i => i.state === 'uploading')
return (
<div className={`upload-box upload-compact${drag ? ' drag' : ''}`}>
<div className={`upload-box upload-large${drag ? ' drag' : ''}`}>
{drag && (
<div className="drop-overlay" aria-hidden="true">
<div><Icon name="upload" /><b>{t('brain.dropHere')}</b></div>

View File

@@ -67,7 +67,7 @@ export function ProductionPage() {
<div><small>{t('prod.links')}</small>{graph ? <b>{graph.links.filter(l => !l.hub).length}</b> : <b>-</b>}<span>{t('prod.linksSub')}</span></div>
</div>
<h3>{t('prod.scheduleTitle')}</h3>
{schedules.data?.length === 0 && <p className="graph-empty">{t('prod.noSchedules')} <Link to="/instruction">{t('prod.giveInstruction')}</Link></p>}
{schedules.data?.length === 0 && <p className="graph-empty">{t('prod.noSchedules')} <Link to="/brain">{t('prod.giveInstruction')}</Link></p>}
<ul className="graph-list">
{schedules.data?.slice(0, 4).map(s => (
<li key={s.agent.id}>

View File

@@ -105,7 +105,7 @@ function NoResults({ filtered, icon }: { filtered: boolean; icon: IconName }) {
<span className="empty-icon"><Icon name={icon} /></span>
<h3>{t('res.empty')}</h3>
<p>{t('res.emptyCopy')}</p>
<Link className="btn light" to="/instruction"><Icon name="plus" />{t('sch.newInstruction')}</Link>
<Link className="btn light" to="/brain"><Icon name="plus" />{t('sch.newInstruction')}</Link>
</div>
)
}
@@ -427,7 +427,7 @@ function SourceRow({ source: s }: { source: FoundSource }) {
<div>
<span className={`status ${tone}`}><i className="dot"></i>{label}</span>
<h3>{s.url ? <a href={s.url} target="_blank" rel="noreferrer">{s.title}</a> : s.title}</h3>
<p>{describeRule(s.rule)} · {fmt(s.createdAt)}{s.status === 'accepted' && <> · <Link to="/brain">{t('res.inBrain')}</Link></>}</p>
<p>{describeRule(s.rule)} · {fmt(s.createdAt)}{s.status === 'accepted' && <> · <Link to="/upload">{t('res.inBrain')}</Link></>}</p>
{s.preview && <p className="source-preview">{s.preview}</p>}
{review.error && <span className="error">{review.error.message}</span>}
</div>

View File

@@ -24,7 +24,7 @@ export function SchedulePage() {
return (
<>
<PageHead title={t('sch.title')} description={t('sch.description')}
actions={<Link className="btn primary" to="/instruction"><Icon name="plus" />{t('sch.newInstruction')}</Link>} />
actions={<Link className="btn primary" to="/brain"><Icon name="plus" />{t('sch.newInstruction')}</Link>} />
<div className="card">
<div className="card-head"><h3>{t('sch.cardTitle')}</h3><Icon name="calendar" /></div>
{schedules.isPending && <SkeletonRows label={t('sch.loading')} />}