Fosi Fossil Service
Small teams. Open source. Built on Fossil.

IaC / SwiftFlow

High-performance WMS with wave picking, smart routing, and real-time inventory visibility.

Public | Owner: IaC | Default branch: trunk | Last update: 2026-10-23 14:37

Artifact 3afb90cb5bd4a0fc27691983eddb089713831a9d68e9f3d29b16f11d8b6b6231:


import type { ReactNode } from 'react'

export function Page({
  title,
  extra,
  children,
}: {
  title: string
  extra?: ReactNode
  children: ReactNode
}) {
  return (
    <section className="page">
      <header className="page-head">
        <h1>{title}</h1>
        {extra}
      </header>
      {children}
    </section>
  )
}

export function Banner({ kind, text }: { kind: 'error' | 'ok'; text: string }) {
  if (!text) return null
  return (
    <p className={kind === 'error' ? 'banner error' : 'banner ok'} role="alert">
      {text}
    </p>
  )
}

export function Empty({ text }: { text: string }) {
  return <p className="empty">{text}</p>
}

export function Pager({
  total,
  limit,
  offset,
  onPage,
}: {
  total: number
  limit: number
  offset: number
  onPage: (offset: number) => void
}) {
  const pages = Math.max(1, Math.ceil(total / limit))
  const page = Math.floor(offset / limit) + 1
  return (
    <div className="pager">
      <span>
        共 {total} 条,第 {page} / {pages} 页
      </span>
      <button type="button" disabled={offset <= 0} onClick={() => onPage(Math.max(0, offset - limit))}>
        上一页
      </button>
      <button
        type="button"
        disabled={offset + limit >= total}
        onClick={() => onPage(offset + limit)}
      >
        下一页
      </button>
    </div>
  )
}

export function Field({
  label,
  children,
}: {
  label: string
  children: ReactNode
}) {
  return (
    <label className="field">
      <span>{label}</span>
      {children}
    </label>
  )
}

Clone

You can clone this repository with the following command:

fossil clone https://fosi.dev/IaC/SwiftFlow

Contribute

The best way to contribute is through e-mail. See the project documentation for more details.