DEV Community

Rahul
Rahul

Posted on

Testcraft Studio frontend 27: src/pages/Dashboard.jsx

import React from 'react';
import Icon from '../Icon.jsx';
import { useStudio, workspaceStatus, visibleWorkspaces } from '../store.jsx';
import { Badge, Button, Empty, Heading } from '../ui.jsx';

export default function Dashboard({ navigate }) {
  const { state: s, mutate } = useStudio();
  const list = visibleWorkspaces(s), baselines = s.baselines.filter(b => b.team === s.session.team && ['Active', 'Approved'].includes(b.status));
  const suites = s.suites.filter(suite => list.some(w => w.id === suite.workspaceId));
  const open = w => { mutate(d => { d.activeWorkspaceId = w.id; }); navigate('workspace'); };
  const steps = [ ['folder', 'Create a workspace', 'Give your testing work a dedicated space.', 'workspaces?create'], ['layers', 'Add a System Baseline', 'Upload documents and request approval.', 'baselines?create'], ['chat', 'Explore your evidence', 'Ask the system about uploaded knowledge.', 'chat'], ['spark', 'Generate test cases', 'Use a default or Excel template.', 'readiness'] ];
  return <><Heading eyebrow={`${s.session.team} · YOUR TESTING SPACE`} title="Workspace overview" description="From system knowledge to well-grounded test cases."><Button icon="plus" variant="primary" onClick={() => navigate('workspaces?create')}>Create workspace</Button></Heading>
    <div className="stats-grid">{[{ label: 'Workspaces', value: list.length, icon: 'folder', note: 'Across your team', tone: 'purple', page: 'workspaces' }, { label: 'Approved baselines', value: baselines.length, icon: 'layers', note: 'Ready to use', tone: 'blue', page: 'baselines' }, { label: 'Test suites', value: suites.length, icon: 'checkSquare', note: 'Generated from your evidence', tone: 'green', page: 'suites' }, { label: 'Templates', value: s.templates.filter(t => t.team === s.session.team).length, icon: 'file', note: 'Your preferred output format', tone: 'purple', page: 'templates' }].map(stat => <button className="stat-card" key={stat.label} onClick={() => navigate(stat.page)}><div className="stat-top"><span>{stat.label}</span><span className={`stat-icon soft-${stat.tone}`}><Icon name={stat.icon} size={18}/></span></div><strong>{stat.value}</strong><span className="stat-note">{stat.note}</span></button>)}</div>
    <section className="card start-guide"><div className="section-heading"><h2>A clear path from evidence to tests</h2><Badge tone="purple">Your workflow</Badge></div><div className="onboarding-grid">{steps.map(([icon, title, description, page], index) => <button className="onboarding-step" key={title} onClick={() => navigate(page)}><span className="step-kicker">0{index + 1}<Icon name={icon} size={22}/></span><strong>{title}</strong><p>{description}</p><Icon name="arrow" size={16}/></button>)}</div></section>
    <section className="card workspace-list margin-top"><div className="section-heading"><h2>Your workspaces</h2><button className="text-button" onClick={() => navigate('workspaces')}>View all <Icon name="arrow" size={14}/></button></div>{list.length ? <div className="table-scroll"><table><thead><tr><th>WORKSPACE</th><th>SYSTEM BASELINE</th><th>STATUS</th><th/></tr></thead><tbody>{list.slice(0, 5).map(w => <tr key={w.id}><td><button className="workspace-table-name" onClick={() => open(w)}><span className="table-icon soft-purple"><Icon name="folder" size={17}/></span><span><strong>{w.name}</strong><small>{w.ref}</small></span></button></td><td>{s.baselines.find(b => b.id === w.baselineId)?.ref || 'Not connected yet'}</td><td><Badge>{workspaceStatus(s, w)}</Badge></td><td><Button onClick={() => open(w)}>Open workspace</Button></td></tr>)}</tbody></table></div> : <Empty title="Make room for your first test journey" description="Start with a workspace. You can create its System Baseline next." action={<Button variant="primary" icon="plus" onClick={() => navigate('workspaces?create')}>Create your first workspace</Button>}/>}</section>
  </>;
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)