import { define, Styles } from 'forge' import { allApps } from '../server/apps' import type { AppState } from '../shared/types' const Apps = define('Apps', { margin: '0 auto', width: 750, paddingTop: 20, }) const color = '#00c0c9' const hoverColor = 'magenta' const Link = define({ base: 'a', color, textDecoration: 'none', borderBottom: `1px solid ${color}`, selectors: { '&:hover': { color: hoverColor, cursor: 'pointer' } } }) const AppCard = define('AppCard', { marginBottom: 24, padding: 16, border: '1px solid #333', borderRadius: 8, }) const AppHeader = define('AppHeader', { display: 'flex', alignItems: 'center', gap: 12, marginBottom: 8, }) const AppName = define('AppName', { fontSize: 20, fontWeight: 'bold', margin: 0, }) const State = define('State', { fontSize: 14, padding: '2px 8px', borderRadius: 4, variants: { status: { invalid: { background: '#4a1c1c', color: '#f87171' }, stopped: { background: '#3a3a3a', color: '#9ca3af' }, starting: { background: '#3b3117', color: '#fbbf24' }, running: { background: '#14532d', color: '#4ade80' }, stopping: { background: '#3b3117', color: '#fbbf24' }, } } }) const Info = define('Info', { fontSize: 14, color: '#9ca3af', margin: '4px 0', }) const ActionBar = define('ActionBar', { marginTop: 12, display: 'flex', gap: 8, }) const Button = define({ base: 'button', selectors: { 'form:has(>&)': { display: 'inline' } }, render({ props, parts: { Root } }) { if (!props.post) return {props.children} return (
{props.children}
) } }) const stateLabels: Record = { invalid: 'Invalid', stopped: 'Stopped', starting: 'Starting...', running: 'Running', stopping: 'Stopping...', } export default () => (

🐾 Apps

{allApps().map(app => ( {app.state === 'running' && app.port ? ( {app.name} ) : ( app.name )} {stateLabels[app.state]} {app.port && Port: {app.port}} {app.started && Started: {new Date(app.started).toLocaleString()}} {app.state === 'stopped' && ( )} {app.state === 'running' && ( <> )} {app.state === 'invalid' && ( Missing or invalid package.json )} ))}
)