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 3ecf300708844e7c5b6b3e805c1b45ded4614da8fc80dc7476d95039f72b4c3c:


import { useState, type FormEvent } from 'react'
import { Banner, Field } from '../ui'
import { useSession } from '../session'

export function Login() {
  const { login } = useSession()
  const [username, setUsername] = useState('')
  const [password, setPassword] = useState('')
  const [error, setError] = useState('')
  const [pending, setPending] = useState(false)

  async function onSubmit(event: FormEvent) {
    event.preventDefault()
    setPending(true)
    setError('')
    try {
      await login(username, password)
    } catch (err) {
      setError(err instanceof Error ? err.message : '登录失败')
    } finally {
      setPending(false)
    }
  }

  return (
    <div className="login-screen">
      <div className="login-card">
        <h1>SwiftFlow</h1>
        <p className="sub">仓储管理控制台</p>
        <form onSubmit={onSubmit}>
          <Banner kind="error" text={error} />
          <Field label="账号">
            <input
              autoFocus
              autoComplete="username"
              value={username}
              onChange={(event) => setUsername(event.target.value)}
            />
          </Field>
          <Field label="密码">
            <input
              type="password"
              autoComplete="current-password"
              value={password}
              onChange={(event) => setPassword(event.target.value)}
            />
          </Field>
          <button type="submit" disabled={pending || !username || !password}>
            {pending ? '正在登录…' : '登录'}
          </button>
        </form>
      </div>
    </div>
  )
}

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.