好的,我们可以在计算器中添加数字按钮,并使用 UnoCSS 来美化界面。以下是修改后的代码:

  1. 首先,安装必要的依赖:
bun add @unocss/core unocss @unocss/preset-uno @elysiajs/html
  1. 修改 server.ts:
import { Elysia } from 'elysia'
import { staticPlugin } from '@elysiajs/static'
import { html } from '@elysiajs/html'
import React from 'react'
import { renderToString } from 'react-dom/server'
import { Calculator } from './components/Calculator'
import { createGenerator } from '@unocss/core'
import presetUno from '@unocss/preset-uno'
 
const uno = createGenerator({
  presets: [presetUno()],
})
 
const app = new Elysia()
  .use(staticPlugin())
  .use(html())
 
app.get('/', async ({ html }) => {
  const calculatorHtml = renderToString(React.createElement(Calculator))
  const { css } = await uno.generate(calculatorHtml)
  
  return html(
    `<!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Complex Calculator</title>
      <script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
      <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
      <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
      <style>${css}</style>
    </head>
    <body>
      <div id="root">${calculatorHtml}</div>
      <script type="text/babel" src="/static/client.js"></script>
    </body>
    </html>`
  )
})
 
// ... 保留原有的 /calculate 路由和其他代码 ...
 
app.listen(3000)
 
console.log('Server is running on http://localhost:3000')
  1. 修改 components/Calculator.tsx:
import React, { useState } from 'react'
 
const themes = {
  light: 'bg-white text-black',
  dark: 'bg-gray-800 text-white',
  colorful: 'bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 text-white',
}
 
export const Calculator: React.FC = () => {
  const [operation, setOperation] = useState('')
  const [values, setValues] = useState('')
  const [result, setResult] = useState<number | null>(null)
  const [theme, setTheme] = useState('light')
  const [layout, setLayout] = useState('vertical')
 
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    const response = await fetch('/calculate', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ operation, values: values.split(',').map(Number) }),
    })
    const data = await response.json()
    setResult(data.result)
  }
 
  const handleNumberClick = (num: number) => {
    setValues(prev => prev + (prev ? ',' : '') + num)
  }
 
  const handleClear = () => {
    setValues('')
    setResult(null)
  }
 
  return (
    <div className={`p-4 ${themes[theme as keyof typeof themes]} ${layout === 'vertical' ? 'flex flex-col' : 'flex flex-row'}`}>
      <div className="flex-1">
        <h1 className="text-2xl font-bold mb-4">Complex Calculator</h1>
        <form onSubmit={handleSubmit} className="mb-4">
          <select 
            value={operation} 
            onChange={(e) => setOperation(e.target.value)}
            className="w-full p-2 mb-2 border rounded"
          >
            <option value="">Select operation</option>
            <option value="sin">Sin</option>
            <option value="cos">Cos</option>
            <option value="tan">Tan</option>
            <option value="mean">Mean</option>
            <option value="median">Median</option>
          </select>
          <input
            type="text"
            value={values}
            onChange={(e) => setValues(e.target.value)}
            placeholder="Enter values (comma-separated)"
            className="w-full p-2 mb-2 border rounded"
          />
          <button type="submit" className="w-full p-2 bg-blue-500 text-white rounded hover:bg-blue-600">Calculate</button>
        </form>
        {result !== null && <p className="text-xl">Result: {result}</p>}
        
        <div className="grid grid-cols-3 gap-2 mt-4">
          {[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].map((num) => (
            <button
              key={num}
              onClick={() => handleNumberClick(num)}
              className="p-2 bg-gray-200 rounded hover:bg-gray-300"
            >
              {num}
            </button>
          ))}
          <button
            onClick={handleClear}
            className="p-2 bg-red-500 text-white rounded hover:bg-red-600 col-span-3"
          >
            Clear
          </button>
        </div>
      </div>
      
      <div className={`${layout === 'vertical' ? 'mt-4' : 'ml-4'}`}>
        <h2 className="text-xl font-bold mb-2">Customize</h2>
        <select 
          value={theme} 
          onChange={(e) => setTheme(e.target.value)}
          className="w-full p-2 mb-2 border rounded"
        >
          <option value="light">Light Theme</option>
          <option value="dark">Dark Theme</option>
          <option value="colorful">Colorful Theme</option>
        </select>
        <select 
          value={layout} 
          onChange={(e) => setLayout(e.target.value)}
          className="w-full p-2 mb-2 border rounded"
        >
          <option value="vertical">Vertical Layout</option>
          <option value="horizontal">Horizontal Layout</option>
        </select>
      </div>
    </div>
  )
}
  1. 修改 static/client.js:
ReactDOM.hydrate(
  React.createElement(Calculator),
  document.getElementById('root')
)

这些修改添加了以下功能:

  1. 数字按钮:用户现在可以点击数字按钮来输入值,而不仅仅是手动输入。
  2. 清除按钮:允许用户快速清除输入和结果。
  3. UnoCSS 样式:使用 UnoCSS 的工具类来美化界面,包括响应式布局、颜色主题等。
  4. 主题切换:现在使用 UnoCSS 的类来切换主题,而不是内联样式。

注意,我们不再需要单独的 styles.css 文件,因为所有的样式都通过 UnoCSS 的工具类来实现。

要运行这个增强版的计算器应用,确保你已经安装了所有必要的依赖,然后使用 bun start 命令启动服务器。

这个版本的计算器不仅功能更加完善,而且界面也更加美观和响应式。你可以根据需要进一步调整样式和布局。