From a22b38babbc6f606928bc74bcb13c171c0595145 Mon Sep 17 00:00:00 2001 From: patdelphi Date: Tue, 19 Aug 2025 22:27:40 +0800 Subject: [PATCH] Merge dev branch: Complete UI optimization with Chinese design system - Implement comprehensive Chinese-style component library - Add unified typography system with semantic font classes - Optimize all pages with responsive design and Chinese aesthetics - Fix button styling and enhance user experience - Add loading states, empty states, and toast notifications - Complete 12 Palaces Details optimization - Establish consistent color scheme and visual hierarchy --- .gitignore | 4 +- TYPOGRAPHY_GUIDE.md | 265 +++++++++++++++ UI_OPTIMIZATION_PLAN.md | 208 ++++++++++++ create_function_templates.ps1 | 71 ---- package.json | 6 +- pnpm-lock.yaml | 6 +- server/index.js | 0 server/middleware/auth.js | 0 server/middleware/errorHandler.js | 0 server/middleware/logger.js | 0 server/routes/analysis.js | 0 server/routes/auth.js | 0 server/routes/history.js | 0 server/routes/profile.js | 0 server/scripts/initDatabase.js | 0 server/services/baziAnalyzer.js | 0 server/services/yijingAnalyzer.js | 0 server/services/ziweiAnalyzer.js | 0 src/components/BaziAnalysisDisplay.tsx | 4 +- src/components/CompleteBaziAnalysis.tsx | 2 +- src/components/CompleteZiweiAnalysis.tsx | 180 ++++++---- src/components/Layout.tsx | 192 ++++++++--- src/components/ui/ChineseButton.tsx | 98 ++++++ src/components/ui/ChineseCard.tsx | 233 +++++++++++++ src/components/ui/ChineseEmpty.tsx | 91 ++++++ src/components/ui/ChineseInput.tsx | 115 +++++++ src/components/ui/ChineseLoading.tsx | 99 ++++++ src/components/ui/ChineseSelect.tsx | 160 +++++++++ src/components/ui/ChineseToast.tsx | 109 +++++++ src/index.css | 227 ++++++++++++- src/pages/AnalysisPage.tsx | 151 +++++---- src/pages/HistoryPage.tsx | 192 +++++------ src/pages/HomePage.tsx | 94 +++--- src/pages/LoginPage.tsx | 89 ++--- src/pages/ProfilePage.tsx | 89 ++--- src/pages/RegisterPage.tsx | 65 ++-- src/styles/typography.css | 274 ++++++++++++++++ tailwind.config.js | 180 +++++++++- tests/integration.test.cjs | 308 ++++++++++++++++++ .../index.js => tests/integration.test.js | 0 40 files changed, 3011 insertions(+), 501 deletions(-) create mode 100644 TYPOGRAPHY_GUIDE.md create mode 100644 UI_OPTIMIZATION_PLAN.md delete mode 100644 create_function_templates.ps1 delete mode 100644 server/index.js delete mode 100644 server/middleware/auth.js delete mode 100644 server/middleware/errorHandler.js delete mode 100644 server/middleware/logger.js delete mode 100644 server/routes/analysis.js delete mode 100644 server/routes/auth.js delete mode 100644 server/routes/history.js delete mode 100644 server/routes/profile.js delete mode 100644 server/scripts/initDatabase.js delete mode 100644 server/services/baziAnalyzer.js delete mode 100644 server/services/yijingAnalyzer.js delete mode 100644 server/services/ziweiAnalyzer.js create mode 100644 src/components/ui/ChineseButton.tsx create mode 100644 src/components/ui/ChineseCard.tsx create mode 100644 src/components/ui/ChineseEmpty.tsx create mode 100644 src/components/ui/ChineseInput.tsx create mode 100644 src/components/ui/ChineseLoading.tsx create mode 100644 src/components/ui/ChineseSelect.tsx create mode 100644 src/components/ui/ChineseToast.tsx create mode 100644 src/styles/typography.css create mode 100644 tests/integration.test.cjs rename server/database/index.js => tests/integration.test.js (100%) diff --git a/.gitignore b/.gitignore index b92f476..b163764 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,6 @@ temp/ *.ntvs* *.njsproj *.sln -*.sw? \ No newline at end of file +*.sw? +numerology.db-shm +numerology.db-wal diff --git a/TYPOGRAPHY_GUIDE.md b/TYPOGRAPHY_GUIDE.md new file mode 100644 index 0000000..a27609f --- /dev/null +++ b/TYPOGRAPHY_GUIDE.md @@ -0,0 +1,265 @@ +# 神机阁字体规范指南 + +## 📖 概述 + +本指南定义了神机阁项目的统一字体规范系统,旨在解决项目中字体大小混乱的问题,建立一致的视觉层次和用户体验。 + +## 🎯 设计原则 + +1. **语义化命名** - 使用语义化的类名,如 `text-heading-lg` 而不是 `text-2xl` +2. **响应式优先** - 所有字体规范都考虑了移动端适配 +3. **可访问性** - 确保足够的对比度和可读性 +4. **一致性** - 统一的行高、字重和字间距规范 +5. **中文优化** - 专门为中文内容优化的字体栈 + +## 📏 字体规范系统 + +### 🏆 显示级标题 (Display) +用于首页主标题和重要页面的超大标题 + +```css +.text-display-xl /* 56px - 首页主标题 */ +.text-display-lg /* 48px - 重要页面标题 */ +.text-display-md /* 40px - 次要页面标题 */ +``` + +**使用场景:** +- 首页 Hero 区域主标题 +- 重要功能页面的主标题 +- 营销页面的大标题 + +### 📝 标题系列 (Heading) +用于页面内容的层次化标题 + +```css +.text-heading-xl /* 32px - H1 标题 */ +.text-heading-lg /* 28px - H2 标题 */ +.text-heading-md /* 24px - H3 标题 */ +.text-heading-sm /* 20px - H4 标题 */ +.text-heading-xs /* 18px - H5 标题 */ +``` + +**使用场景:** +- 页面主标题 (H1) +- 章节标题 (H2-H3) +- 卡片标题 (H4-H5) +- 组件内部标题 + +### 📄 正文系列 (Body) +用于页面的主要内容文字 + +```css +.text-body-xl /* 18px - 重要描述文字 */ +.text-body-lg /* 16px - 标准正文 (默认) */ +.text-body-md /* 14px - 次要正文 */ +.text-body-sm /* 12px - 辅助信息 */ +``` + +**使用场景:** +- 重要的介绍文字 (body-xl) +- 标准正文内容 (body-lg) +- 卡片描述文字 (body-md) +- 提示信息、时间戳 (body-sm) + +### 🏷️ 标签系列 (Label) +用于表单标签和小标签 + +```css +.text-label-lg /* 14px - 表单标签 */ +.text-label-md /* 12px - 小标签 */ +.text-label-sm /* 11px - 微小标签 */ +``` + +**使用场景:** +- 表单字段标签 +- 状态标签 +- 分类标签 +- 徽章文字 + +### 🔘 按钮系列 (Button) +用于按钮内的文字 + +```css +.text-button-lg /* 16px - 大按钮 */ +.text-button-md /* 14px - 标准按钮 */ +.text-button-sm /* 12px - 小按钮 */ +``` + +**使用场景:** +- 主要操作按钮 (button-lg) +- 标准按钮 (button-md) +- 次要按钮和图标按钮 (button-sm) + +## 🎨 字体族规范 + +### 中文字体栈 +```css +.font-chinese +/* 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', 'Noto Sans SC', 'STHeiti', 'WenQuanYi Micro Hei', sans-serif */ +``` + +### 中文衬线字体 +```css +.font-chinese-serif +/* 'Noto Serif SC', 'STSong', 'SimSun', '宋体', serif */ +``` + +### 英文字体 +```css +.font-english +/* 'Inter', 'Helvetica Neue', 'Arial', sans-serif */ +``` + +### 数字字体 +```css +.font-numeric +/* 确保数字对齐的等宽字体 */ +``` + +## 📱 响应式规范 + +所有字体规范都内置了响应式适配: + +- **移动端 (≤768px)**: 字体大小适当缩小 +- **超小屏 (≤480px)**: 进一步优化字体大小 +- **桌面端 (>768px)**: 使用标准字体大小 + +## 🔧 使用方法 + +### 1. HTML 中使用 +```html + +

神机阁

+ + +

八字命理

+ + +

这是标准正文内容

+ + + +``` + +### 2. React 组件中使用 +```jsx +// 推荐:使用语义化类名 + + 十二宫位详解 + + +// 避免:使用数字类名 + + 十二宫位详解 + +``` + +### 3. CSS 中使用 +```css +/* 自定义组件样式 */ +.custom-title { + @apply text-heading-lg font-chinese font-semibold; + color: var(--cinnabar-500); +} +``` + +## 🎯 迁移指南 + +### 常见替换映射 + +| 旧类名 | 新类名 | 用途 | +|--------|--------|------| +| `text-3xl` | `text-display-md` | 页面主标题 | +| `text-2xl` | `text-heading-xl` | 大标题 | +| `text-xl` | `text-heading-lg` | 中标题 | +| `text-lg` | `text-heading-md` | 小标题 | +| `text-base` | `text-body-lg` | 标准正文 | +| `text-sm` | `text-body-md` | 次要正文 | +| `text-xs` | `text-body-sm` | 辅助信息 | + +### 迁移步骤 + +1. **识别用途** - 确定文字的语义用途(标题、正文、标签等) +2. **选择规范** - 根据用途选择对应的字体规范 +3. **添加字体族** - 确保添加 `font-chinese` 类 +4. **测试响应式** - 在不同设备上测试显示效果 + +## ✅ 最佳实践 + +### ✅ 推荐做法 + +```html + +

神机阁

+

命理分析

+

专业的命理分析服务

+ + + +2024 + + +

神机阁

+``` + +### ❌ 避免做法 + +```html + +

标题

+

正文

+ + +

标题

+ + + +

正文

+``` + +## 🔍 常见问题 + +### Q: 什么时候使用 display 系列? +A: 仅用于首页主标题和重要页面的超大标题,不要在普通内容中使用。 + +### Q: 如何选择合适的字体大小? +A: 根据内容的重要性和层次选择: +- 页面标题 → heading 系列 +- 正文内容 → body 系列 +- 表单标签 → label 系列 +- 按钮文字 → button 系列 + +### Q: 移动端需要特殊处理吗? +A: 不需要,所有字体规范都内置了响应式适配。 + +### Q: 可以自定义字体大小吗? +A: 不推荐。如果确实需要,请先考虑是否可以使用现有规范,或者提出新的规范需求。 + +## 📊 字体规范对照表 + +| 类名 | 桌面端 | 移动端 | 行高 | 字重 | 用途 | +|------|--------|--------|------|------|------| +| `text-display-xl` | 56px | 40px | 1.1 | 800 | 首页主标题 | +| `text-display-lg` | 48px | 36px | 1.1 | 700 | 重要页面标题 | +| `text-display-md` | 40px | 32px | 1.2 | 700 | 次要页面标题 | +| `text-heading-xl` | 32px | 28px | 1.25 | 600 | H1 标题 | +| `text-heading-lg` | 28px | 24px | 1.3 | 600 | H2 标题 | +| `text-heading-md` | 24px | 20px | 1.35 | 600 | H3 标题 | +| `text-heading-sm` | 20px | 18px | 1.4 | 600 | H4 标题 | +| `text-heading-xs` | 18px | 16px | 1.4 | 600 | H5 标题 | +| `text-body-xl` | 18px | 16px | 1.6 | 400 | 重要描述 | +| `text-body-lg` | 16px | 16px | 1.6 | 400 | 标准正文 | +| `text-body-md` | 14px | 14px | 1.6 | 400 | 次要正文 | +| `text-body-sm` | 12px | 12px | 1.5 | 400 | 辅助信息 | +| `text-label-lg` | 14px | 14px | 1.4 | 500 | 表单标签 | +| `text-label-md` | 12px | 12px | 1.4 | 500 | 小标签 | +| `text-label-sm` | 11px | 11px | 1.4 | 500 | 微小标签 | +| `text-button-lg` | 16px | 16px | 1.4 | 600 | 大按钮 | +| `text-button-md` | 14px | 14px | 1.4 | 600 | 标准按钮 | +| `text-button-sm` | 12px | 12px | 1.4 | 600 | 小按钮 | + +--- + +**更新日期**: 2024年12月 +**版本**: 1.0.0 +**维护者**: 神机阁开发团队 \ No newline at end of file diff --git a/UI_OPTIMIZATION_PLAN.md b/UI_OPTIMIZATION_PLAN.md new file mode 100644 index 0000000..10e5b67 --- /dev/null +++ b/UI_OPTIMIZATION_PLAN.md @@ -0,0 +1,208 @@ +# 神机阁 UI 优化计划 + +## 🎯 优化目标 + +- 解决移动端顶部字体溢出问题 +- 建立统一的中式风格设计系统 +- 实现完美的桌面端与移动端自适应 +- 创造优雅古典的用户体验 +- 优化色彩搭配和视觉层次 + +## 📋 当前问题分析 + +### 1. 移动端问题 +- 顶部导航字体溢出 +- 布局在小屏幕上不合理 +- 触摸交互体验不佳 + +### 2. 整体设计问题 +- 字体大小不统一 +- 缺乏视觉层次 +- 色彩搭配不和谐 +- 缺乏中式设计元素的统一性 + +## 🎨 设计系统规划 + +### 1. 色彩系统 (中式古典配色) + +#### 主色调 +- **朱砂红**: `#DC143C` - 主要强调色,用于重要按钮和标题 +- **金黄色**: `#FFD700` - 辅助色,用于装饰和高亮 +- **墨黑色**: `#2C2C2C` - 主要文字色 +- **古纸色**: `#F5F5DC` - 背景色 +- **青灰色**: `#708090` - 次要文字色 + +#### 渐变背景 +- **主背景**: 从古纸色到淡金色的渐变 +- **卡片背景**: 半透明白色覆盖 +- **按钮渐变**: 朱砂红到深红的渐变 + +### 2. 字体系统 + +#### 字体族 +```css +/* 中文优先字体栈 */ +font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', 'STHeiti', 'WenQuanYi Micro Hei', sans-serif; +``` + +#### 字体大小规范 +- **标题 H1**: 2.5rem (40px) / 移动端 2rem (32px) +- **标题 H2**: 2rem (32px) / 移动端 1.75rem (28px) +- **标题 H3**: 1.5rem (24px) / 移动端 1.25rem (20px) +- **正文**: 1rem (16px) / 移动端 0.875rem (14px) +- **小字**: 0.875rem (14px) / 移动端 0.75rem (12px) + +#### 行高规范 +- **标题**: 1.2 +- **正文**: 1.6 +- **按钮文字**: 1.4 + +### 3. 间距系统 + +#### 基础间距单位 (基于 4px) +- **xs**: 0.25rem (4px) +- **sm**: 0.5rem (8px) +- **md**: 1rem (16px) +- **lg**: 1.5rem (24px) +- **xl**: 2rem (32px) +- **2xl**: 3rem (48px) + +### 4. 组件设计规范 + +#### 按钮设计 +- **主按钮**: 朱砂红背景,金色边框,白色文字 +- **次按钮**: 透明背景,朱砂红边框,朱砂红文字 +- **圆角**: 8px +- **高度**: 44px (移动端友好) +- **内边距**: 16px 24px + +#### 卡片设计 +- **背景**: 半透明白色 rgba(255,255,255,0.9) +- **边框**: 1px solid rgba(220,20,60,0.2) +- **圆角**: 12px +- **阴影**: 0 4px 20px rgba(0,0,0,0.1) +- **内边距**: 24px + +#### 输入框设计 +- **背景**: 白色 +- **边框**: 1px solid #E5E5E5 +- **聚焦边框**: 2px solid #DC143C +- **圆角**: 6px +- **高度**: 44px +- **内边距**: 12px 16px + +## 📱 响应式设计策略 + +### 1. 断点设置 +```css +/* 移动端 */ +@media (max-width: 768px) { ... } + +/* 平板端 */ +@media (min-width: 769px) and (max-width: 1024px) { ... } + +/* 桌面端 */ +@media (min-width: 1025px) { ... } +``` + +### 2. 移动端优化 +- **导航栏**: 汉堡菜单,避免文字溢出 +- **字体缩放**: 移动端字体适当缩小 +- **触摸目标**: 最小 44px × 44px +- **间距调整**: 移动端间距适当减小 + +### 3. 布局策略 +- **桌面端**: 多列布局,侧边栏导航 +- **移动端**: 单列布局,底部导航 +- **弹性布局**: 使用 Flexbox 和 Grid + +## 🎭 中式设计元素 + +### 1. 装饰元素 +- **云纹图案**: 作为背景装饰 +- **回纹边框**: 用于卡片和分割线 +- **印章样式**: 用于重要标识 +- **书法笔触**: 用于标题装饰 + +### 2. 图标设计 +- **八卦图标**: 用于导航和功能区分 +- **中式符号**: 太极、阴阳、五行元素 +- **传统色彩**: 朱砂、金黄、墨色 + +### 3. 动画效果 +- **淡入淡出**: 页面切换动画 +- **缓动函数**: cubic-bezier(0.4, 0, 0.2, 1) +- **悬停效果**: 轻微的缩放和阴影变化 + +## 🔧 技术实现方案 + +### 1. CSS 架构 +- **原子化 CSS**: 使用 Tailwind CSS +- **自定义主题**: 扩展 Tailwind 配置 +- **组件样式**: CSS Modules 或 Styled Components + +### 2. 响应式实现 +- **移动优先**: Mobile-first 设计 +- **弹性单位**: rem, em, vw, vh +- **媒体查询**: 断点式响应 + +### 3. 性能优化 +- **字体优化**: 字体子集化,预加载 +- **图片优化**: WebP 格式,懒加载 +- **CSS 优化**: 关键 CSS 内联 + +## 📋 实施计划 + +### 阶段一:基础设施 (1-2天) +1. 更新 Tailwind 配置,添加中式主题 +2. 创建设计系统组件库 +3. 建立响应式断点系统 + +### 阶段二:核心组件 (2-3天) +1. 重构导航栏组件 (解决移动端溢出) +2. 优化按钮和表单组件 +3. 重设计卡片和布局组件 + +### 阶段三:页面优化 (3-4天) +1. 首页重新设计 +2. 分析页面布局优化 +3. 历史记录页面改进 +4. 用户中心页面美化 + +### 阶段四:细节完善 (1-2天) +1. 动画效果添加 +2. 交互细节优化 +3. 跨设备测试 +4. 性能优化 + +## 🎯 预期效果 + +### 视觉效果 +- 统一的中式古典风格 +- 和谐的色彩搭配 +- 清晰的视觉层次 +- 优雅的动画过渡 + +### 用户体验 +- 完美的移动端适配 +- 直观的导航体验 +- 舒适的阅读体验 +- 流畅的交互反馈 + +### 技术指标 +- 移动端适配率 100% +- 页面加载速度 < 2s +- 交互响应时间 < 100ms +- 跨浏览器兼容性 95%+ + +## 📝 验收标准 + +1. **移动端测试**: 在各种移动设备上无溢出、布局正常 +2. **响应式测试**: 在不同屏幕尺寸下表现良好 +3. **视觉一致性**: 所有页面遵循统一设计规范 +4. **性能测试**: 页面加载和交互性能达标 +5. **用户体验**: 导航清晰、操作便捷、视觉舒适 + +--- + +*此计划将分阶段实施,每个阶段完成后进行测试和调整,确保最终效果符合预期。* \ No newline at end of file diff --git a/create_function_templates.ps1 b/create_function_templates.ps1 deleted file mode 100644 index 2b9f9fb..0000000 --- a/create_function_templates.ps1 +++ /dev/null @@ -1,71 +0,0 @@ -# PowerShell script to create template files for all remaining Edge Functions - -$functions = @( - 'numerology-analysis', - 'reading-history', - 'yijing-analyzer', - 'bazi-analysis', - 'ziwei-analysis', - 'yijing-analysis', - 'create-user-simple', - 'create-admin-user', - 'custom-auth', - 'profile-manager', - 'wuxing-analysis', - 'bazi-detail-analysis', - 'bazi-wuxing-analysis', - 'bazi-details' -) - -$template = @' -// Supabase Edge Function: {0} -// TODO: Copy the actual code from Supabase Dashboard - -import { serve } from 'https://deno.land/std@0.168.0/http/server.ts' -import { createClient } from 'https://esm.sh/@supabase/supabase-js@2' - -const corsHeaders = { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type', -} - -serve(async (req) => { - // Handle CORS preflight requests - if (req.method === 'OPTIONS') { - return new Response('ok', { headers: corsHeaders }) - } - - try { - // TODO: Replace with actual implementation from Dashboard - return new Response( - JSON.stringify({ message: '{0} function - replace with actual code' }), - { - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - } - ) - } catch (error) { - return new Response( - JSON.stringify({ error: error.message }), - { - status: 500, - headers: { ...corsHeaders, 'Content-Type': 'application/json' }, - } - ) - } -}) -'@ - -foreach ($func in $functions) { - $functionName = $func -replace '-', ' ' | ForEach-Object { (Get-Culture).TextInfo.ToTitleCase($_) } - $content = $template -f $functionName, $func - $filePath = "supabase\functions\$func\index.ts" - - if (!(Test-Path $filePath)) { - $content | Out-File -FilePath $filePath -Encoding UTF8 - Write-Host "Created: $filePath" - } else { - Write-Host "Already exists: $filePath" - } -} - -Write-Host "All function templates created successfully!" \ No newline at end of file diff --git a/package.json b/package.json index f28b5b3..95ec73c 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,9 @@ "lint": "eslint .", "preview": "vite preview", "start": "node server/index.cjs", - "db:init": "node server/scripts/initDatabase.cjs" + "db:init": "node server/scripts/initDatabase.cjs", + "test": "node tests/integration.test.cjs", + "test:integration": "node tests/integration.test.cjs" }, "dependencies": { "@hookform/resolvers": "^3.10.0", @@ -58,7 +60,6 @@ "jsonwebtoken": "^9.0.2", "lucide-react": "^0.364.0", "next-themes": "^0.4.4", - "node-fetch": "^2.7.0", "nodemon": "^3.0.2", "react": "^18.3.1", "react-day-picker": "8.10.1", @@ -89,6 +90,7 @@ "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.14", "globals": "^15.12.0", + "node-fetch": "^2.7.0", "postcss": "8.4.49", "tailwindcss": "v3.4.16", "typescript": "~5.6.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd60f40..66fe398 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -137,9 +137,6 @@ importers: next-themes: specifier: ^0.4.4 version: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - node-fetch: - specifier: ^2.7.0 - version: 2.7.0 nodemon: specifier: ^3.0.2 version: 3.1.10 @@ -225,6 +222,9 @@ importers: globals: specifier: ^15.12.0 version: 15.15.0 + node-fetch: + specifier: ^2.7.0 + version: 2.7.0 postcss: specifier: 8.4.49 version: 8.4.49 diff --git a/server/index.js b/server/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/middleware/auth.js b/server/middleware/auth.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/middleware/errorHandler.js b/server/middleware/errorHandler.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/middleware/logger.js b/server/middleware/logger.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/routes/analysis.js b/server/routes/analysis.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/routes/auth.js b/server/routes/auth.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/routes/history.js b/server/routes/history.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/routes/profile.js b/server/routes/profile.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/scripts/initDatabase.js b/server/scripts/initDatabase.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/services/baziAnalyzer.js b/server/services/baziAnalyzer.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/services/yijingAnalyzer.js b/server/services/yijingAnalyzer.js deleted file mode 100644 index e69de29..0000000 diff --git a/server/services/ziweiAnalyzer.js b/server/services/ziweiAnalyzer.js deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/BaziAnalysisDisplay.tsx b/src/components/BaziAnalysisDisplay.tsx index 8aec65a..cc8534a 100644 --- a/src/components/BaziAnalysisDisplay.tsx +++ b/src/components/BaziAnalysisDisplay.tsx @@ -395,7 +395,7 @@ const BaziAnalysisDisplay: React.FC = ({ birthDate }) {/* 天干信息 */}

天干:{pillar.tiangan}

-
+
五行:{pillar.tianganWuxing}
@@ -408,7 +408,7 @@ const BaziAnalysisDisplay: React.FC = ({ birthDate }) {/* 地支信息 */}

地支:{pillar.dizhi}

-
+
五行:{pillar.dizhiWuxing}
diff --git a/src/components/CompleteBaziAnalysis.tsx b/src/components/CompleteBaziAnalysis.tsx index e675235..09b8df0 100644 --- a/src/components/CompleteBaziAnalysis.tsx +++ b/src/components/CompleteBaziAnalysis.tsx @@ -236,7 +236,7 @@ const CompleteBaziAnalysis: React.FC = ({ birthDate, const total = Object.values(elements).reduce((sum: number, count: any) => sum + (typeof count === 'number' ? count : 0), 0) as number; return ( -
+
{Object.entries(elements).map(([element, count]) => { const numCount = typeof count === 'number' ? count : 0; const percentage = total > 0 ? Math.round((numCount / total) * 100) : 0; diff --git a/src/components/CompleteZiweiAnalysis.tsx b/src/components/CompleteZiweiAnalysis.tsx index 65c90cc..a7d906f 100644 --- a/src/components/CompleteZiweiAnalysis.tsx +++ b/src/components/CompleteZiweiAnalysis.tsx @@ -2,7 +2,10 @@ import React, { useState, useEffect } from 'react'; import { Radar, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, ResponsiveContainer } from 'recharts'; import { Calendar, Star, BookOpen, Sparkles, User, BarChart3, Zap, TrendingUp, Loader2, Clock, Target, Heart, DollarSign, Activity, Crown, Compass, Moon, Sun } from 'lucide-react'; import { Card, CardContent, CardHeader, CardTitle } from './ui/Card'; +import { ChineseCard, ChineseCardContent, ChineseCardHeader, ChineseCardTitle } from './ui/ChineseCard'; +import { ChineseLoading } from './ui/ChineseLoading'; import { localApi } from '../lib/localApi'; +import { cn } from '../lib/utils'; interface CompleteZiweiAnalysisProps { birthDate: { @@ -211,35 +214,35 @@ const CompleteZiweiAnalysis: React.FC = ({ birthDate } }; - // 星曜颜色配置 + // 星曜颜色配置(中式配色) const starColors: { [key: string]: string } = { - '紫微': 'bg-purple-100 text-purple-800 border-purple-300', + '紫微': 'bg-red-100 text-red-800 border-red-300', '天机': 'bg-blue-100 text-blue-800 border-blue-300', - '太阳': 'bg-orange-100 text-orange-800 border-orange-300', + '太阳': 'bg-yellow-100 text-yellow-800 border-yellow-300', '武曲': 'bg-gray-100 text-gray-800 border-gray-300', '天同': 'bg-green-100 text-green-800 border-green-300', '廉贞': 'bg-red-100 text-red-800 border-red-300', '天府': 'bg-yellow-100 text-yellow-800 border-yellow-300', - '太阴': 'bg-indigo-100 text-indigo-800 border-indigo-300', - '贪狼': 'bg-pink-100 text-pink-800 border-pink-300', - '巨门': 'bg-slate-100 text-slate-800 border-slate-300', - '天相': 'bg-cyan-100 text-cyan-800 border-cyan-300', - '天梁': 'bg-emerald-100 text-emerald-800 border-emerald-300', - '七杀': 'bg-rose-100 text-rose-800 border-rose-300', - '破军': 'bg-amber-100 text-amber-800 border-amber-300' + '太阴': 'bg-blue-100 text-blue-800 border-blue-300', + '贪狼': 'bg-orange-100 text-orange-800 border-orange-300', + '巨门': 'bg-gray-100 text-gray-800 border-gray-300', + '天相': 'bg-green-100 text-green-800 border-green-300', + '天梁': 'bg-yellow-100 text-yellow-800 border-yellow-300', + '七杀': 'bg-red-100 text-red-800 border-red-300', + '破军': 'bg-orange-100 text-orange-800 border-orange-300' }; - // 吉星煞星颜色配置 - const luckyStarColors = 'bg-green-50 text-green-700 border-green-200'; + // 吉星煞星颜色配置(中式配色) + const luckyStarColors = 'bg-yellow-50 text-yellow-700 border-yellow-200'; const unluckyStarColors = 'bg-red-50 text-red-700 border-red-200'; - // 宫位强度颜色 + // 宫位强度颜色(中式配色) const strengthColors: { [key: string]: string } = { - '旺': 'text-green-600 bg-green-50', - '得地': 'text-blue-600 bg-blue-50', - '平': 'text-yellow-600 bg-yellow-50', + '旺': 'text-red-600 bg-red-50', + '得地': 'text-yellow-600 bg-yellow-50', + '平': 'text-gray-600 bg-gray-50', '不得地': 'text-orange-600 bg-orange-50', - '陷': 'text-red-600 bg-red-50' + '陷': 'text-gray-500 bg-gray-100' }; // 五行局颜色 @@ -299,14 +302,19 @@ const CompleteZiweiAnalysis: React.FC = ({ birthDate // 渲染加载状态 if (isLoading) { return ( -
- - - -

正在进行专业紫微斗数分析

-

请稍候,正在排盘并生成您的详细命理报告...

-
-
+
+ + + +

排盘分析中

+

请稍候,正在生成您的详细命理报告...

+
+
); } @@ -346,31 +354,63 @@ const CompleteZiweiAnalysis: React.FC = ({ birthDate ); } - // 渲染宫位卡片 + // 渲染宫位卡片(中式设计) const renderPalaceCard = (palaceName: string, palace: any) => { if (!palace) return null; + // 宫位图标映射 + const palaceIcons: { [key: string]: any } = { + '命宫': User, + '兄弟宫': Heart, + '夫妻宫': Heart, + '子女宫': Star, + '财帛宫': DollarSign, + '疾厄宫': Activity, + '迁移宫': Compass, + '交友宫': Heart, + '事业宫': Crown, + '田宅宫': Target, + '福德宫': Sun, + '父母宫': Moon + }; + + const PalaceIcon = palaceIcons[palaceName] || Star; + return ( - - - - {palaceName} - -
- {palace.position} - - {palace.strength} - + + +
+
+ +
+ + {palaceName} + +
+ {palace.position || palace.branch} + + {palace.strength} + +
- - +
+ {/* 主星 */} {palace.main_stars && palace.main_stars.length > 0 && (
-
主星
+
+ + 主星 +
{palace.main_stars.map((star: string, index: number) => ( - + {star} ))} @@ -381,10 +421,16 @@ const CompleteZiweiAnalysis: React.FC = ({ birthDate {/* 吉星 */} {palace.lucky_stars && palace.lucky_stars.length > 0 && (
-
吉星
+
+ + 吉星 +
{palace.lucky_stars.map((star: string, index: number) => ( - + {star} ))} @@ -395,10 +441,16 @@ const CompleteZiweiAnalysis: React.FC = ({ birthDate {/* 煞星 */} {palace.unlucky_stars && palace.unlucky_stars.length > 0 && (
-
煞星
+
+ + 煞星 +
{palace.unlucky_stars.map((star: string, index: number) => ( - + {star} ))} @@ -408,12 +460,16 @@ const CompleteZiweiAnalysis: React.FC = ({ birthDate {/* 宫位解读 */} {palace.interpretation && ( -
-

{palace.interpretation}

+
+
+ + 宫位解读 +
+

{palace.interpretation}

)} - - + + ); }; @@ -601,22 +657,26 @@ const CompleteZiweiAnalysis: React.FC = ({ birthDate )} {/* 十二宫位详解 */} - - - - - 十二宫位详解 - -

紫微斗数将人生分为十二个宫位,每个宫位代表不同的人生领域

-
- -
+ + +
+
+ +
+ + 十二宫位详解 + +

紫微斗数将人生分为十二个宫位,每个宫位代表不同的人生领域

+
+
+ +
{analysisData.ziwei_analysis?.twelve_palaces && Object.entries(analysisData.ziwei_analysis.twelve_palaces).map(([palaceName, palace]) => renderPalaceCard(palaceName, palace) )}
- - +
+
{/* 四化飞星 */} {analysisData.ziwei_analysis?.si_hua && ( diff --git a/src/components/Layout.tsx b/src/components/Layout.tsx index 4530f1d..8181c03 100644 --- a/src/components/Layout.tsx +++ b/src/components/Layout.tsx @@ -1,9 +1,10 @@ -import React, { ReactNode } from 'react'; +import React, { ReactNode, useState } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { useAuth } from '../contexts/AuthContext'; -import { Sparkles, User, History, LogOut, Home, Stars } from 'lucide-react'; -import { Button } from './ui/Button'; +import { Sparkles, User, History, LogOut, Home, Menu, X } from 'lucide-react'; +import { ChineseButton } from './ui/ChineseButton'; import { toast } from 'sonner'; +import { cn } from '../lib/utils'; interface LayoutProps { children: ReactNode; @@ -12,11 +13,13 @@ interface LayoutProps { const Layout: React.FC = ({ children }) => { const { user, signOut } = useAuth(); const location = useLocation(); + const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); const handleSignOut = async () => { try { await signOut(); toast.success('登出成功'); + setIsMobileMenuOpen(false); } catch (error) { toast.error('登出失败'); } @@ -24,32 +27,44 @@ const Layout: React.FC = ({ children }) => { const navigationItems = [ { path: '/', label: '首页', icon: Home }, - { path: '/analysis', label: '命理分析', icon: Sparkles, requireAuth: true }, - { path: '/history', label: '历史记录', icon: History, requireAuth: true }, - { path: '/profile', label: '个人档案', icon: User, requireAuth: true }, + { path: '/analysis', label: '分析', icon: Sparkles, requireAuth: true }, + { path: '/history', label: '历史', icon: History, requireAuth: true }, + { path: '/profile', label: '档案', icon: User, requireAuth: true }, ]; + const toggleMobileMenu = () => { + console.log('Toggle mobile menu:', !isMobileMenuOpen); + setIsMobileMenuOpen(!isMobileMenuOpen); + }; + + const closeMobileMenu = () => { + setIsMobileMenuOpen(false); + }; + return (
{/* 导航栏 */} -