]> acesimba.cloud Git - words.git/commitdiff
修改首页CSS
authorroot <root@localhost.localdomain>
Sun, 24 May 2026 12:48:21 +0000 (20:48 +0800)
committerroot <root@localhost.localdomain>
Sun, 24 May 2026 12:48:21 +0000 (20:48 +0800)
frontend/src/App.css
frontend/src/components/Home.css
frontend/src/home.js [deleted file]

index 74b5e053450a48a6bdb4d71aad648e7af821975c..7e9f90595a5f66f5561e7172ae2438178f04ba1a 100644 (file)
     transform: rotate(360deg);
   }
 }
+/* 全局基础样式 */
+body {
+  margin: 0;
+  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
+  background-color: #f9fafb; /* 极简浅灰背景 */
+  color: #1a1a1a;
+  -webkit-font-smoothing: antialiased;
+}
+
+.App {
+  max-width: 1000px;
+  margin: 0 auto;
+  padding: 40px 20px;
+}
+
+/* 标题样式 */
+h1 {
+  font-size: 2rem;
+  font-weight: 700;
+  color: #111827;
+  margin-bottom: 30px;
+  text-align: center;
+  letter-spacing: -0.025em;
+}
+
+/* 表格容器:卡片风格 */
+.table-container {
+  background: #ffffff;
+  border-radius: 12px;
+  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
+  overflow: hidden; /* 确保圆角生效 */
+  border: 1px solid #e5e7eb;
+}
+
+/* 表格样式 */
+table {
+  width: 100%;
+  border-collapse: collapse;
+  text-align: left;
+  font-size: 14px;
+}
+
+/* 表头 */
+thead {
+  background-color: #f8fafc;
+  border-bottom: 1px solid #e5e7eb;
+}
+
+th {
+  padding: 12px 16px;
+  font-weight: 600;
+  color: #4b5563;
+  text-transform: uppercase;
+  font-size: 12px;
+  letter-spacing: 0.05em;
+}
+
+/* 单元格 */
+td {
+  padding: 10px 16px;
+  border-bottom: 1px solid #f3f4f6;
+  line-height: 1.5;
+  color: #374151;
+}
+
+/* 紧凑调整:如果是单词列,加粗 */
+td:first-child {
+  font-weight: 600;
+  color: #2563eb; /* 蓝色链接色 */
+  width: 20%;
+}
+
+/* 悬停效果 */
+tr:hover {
+  background-color: #f9fafb;
+  transition: background-color 0.2s ease;
+}
+
+/* 响应式处理 */
+@media (max-width: 600px) {
+  .App {
+    padding: 20px 10px;
+  }
+  th, td {
+    padding: 8px 10px;
+    font-size: 13px;
+  }
+}
index 842caf420331cb31386d226c338de969c1b52317..1c3c9092c3b5828eeb2608130b33041c577e0d27 100644 (file)
-.main-app {
-    background-color: #fdfdfd;
+/* 全局基础样式 - 清爽护眼版 */
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+  }
+  
+  body {
+    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
+    background-color: #f0f7ff;
+    color: #1a1a1a;
+    -webkit-font-smoothing: antialiased;
     min-height: 100vh;
-    padding: 40px;
-    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
-}
-
-.header {
+    padding: 20px 15px;
+  }
+  
+  .App {
+    max-width: 900px;
+    margin: 0 auto;
+    display: flex;
+    flex-direction: column;
+    gap: 24px;
+    align-items: center;
+  }
+  
+  /* 标题样式 */
+  h1 {
+    font-size: 22px;
+    font-weight: 700;
+    color: #1e40af;
     text-align: center;
-    margin-bottom: 20px;
-}
-
-.header h1 {
-    font-size: 28px;
-    color: #2c3e50;
-    margin-bottom: 5px;
-}
-
-.stats-info {
-    color: #7f8c8d;
-    font-size: 14px;
-}
-
-.action-bar {
+    margin: 10px 0;
+  }
+  
+  /* 统计信息居中排版 */
+  .stat-info {
+    text-align: center;
+    font-size: 15px;
+    color: #475569;
+    line-height: 1.8;
+  }
+  
+  /* 按钮组居中布局 */
+  .btn-group {
     display: flex;
+    gap: 16px;
     justify-content: center;
-    margin-bottom: 20px;
-}
-
-.toggle-btn {
-    background: white;
-    border: 1px solid #dee2e6;
-    padding: 8px 20px;
-    color: #6c757d;
+    flex-wrap: wrap;
+  }
+  
+  /* 美化通用按钮样式 */
+  .btn {
+    padding: 10px 24px;
+    border-radius: 8px;
+    border: none;
+    font-size: 14px;
+    font-weight: 500;
     cursor: pointer;
-    border-radius: 4px;
-}
-
-.table-container {
-    background: white;
-    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
-    border-radius: 4px;
+    transition: all 0.2s ease;
+  }
+  
+  .btn-show {
+    background-color: #e0efff;
+    color: #1d4ed8;
+  }
+  
+  .btn-error {
+    background-color: #fef2f2;
+    color: #dc2626;
+  }
+  
+  .btn:hover {
+    transform: translateY(-2px);
+    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
+  }
+  
+  /* 通用容器居中统一样式 */
+  .table-container,
+  .error-mode-wrap {
+    background: #ffffff;
+    border-radius: 16px;
+    box-shadow: 0 8px 24px rgba(17, 24, 39, 0.06);
+    border: none;
     overflow: hidden;
-}
-
-.progress-table {
+    width: 100%;
+    max-width: 700px;
+    margin: 0 auto;
+  }
+  
+  /* 表格样式 */
+  table {
     width: 100%;
     border-collapse: collapse;
-}
-
-.progress-table th {
-    background-color: #f1f3f5;
-    color: #495057;
-    padding: 15px;
-    font-weight: bold;
-    border-bottom: 1px solid #dee2e6;
-}
-
-.progress-table td {
-    padding: 15px;
+    table-layout: fixed;
+  }
+  
+  /* 表头 */
+  th {
+    background-color: #eff6ff;
+    padding: 16px 12px;
+    font-weight: 600;
+    color: #1e40af;
+    font-size: 14px;
+    text-align: center;
+    white-space: nowrap;
+  }
+  
+  /* 表格内容 */
+  td {
+    padding: 16px 12px;
+    font-size: 15px;
+    color: #1f2937;
+    border-bottom: 1px solid #f1f5f9;
     text-align: center;
-    border-bottom: 1px solid #f8f9fa;
-    height: 55px;
-}
-
-.group-name {
-    font-weight: bold;
-    color: #2c3e50;
-}
-
-/* 状态颜色映射 */
-.status-done { color: #28a745; }
-.status-start { color: #007bff; font-weight: bold; }
-.status-warning { color: #dc3545; font-weight: bold; }
-
-.footer {
+  }
+  
+  /* 四列等宽均分 */
+  th:nth-child(1), td:nth-child(1) { width: 25%; font-weight: 600; color: #1d4ed8; }
+  th:nth-child(2), td:nth-child(2) { width: 25%; }
+  th:nth-child(3), td:nth-child(3) { width: 25%; }
+  th:nth-child(4), td:nth-child(4) { width: 25%; color: #64748b; font-size: 13px; }
+  
+  /* 最后一行无边框 */
+  tr:last-child td {
+    border-bottom: none;
+  }
+  
+  /* hover高亮 */
+  tr:hover {
+    background-color: #f8fafc;
+    transition: background-color 0.2s ease;
+  }
+  
+  /* 消错模式整体居中对齐 */
+  .error-mode-wrap {
     display: flex;
-    justify-content: center;
-    margin-top: 40px;
-}
-
-.error-correction-btn {
-    background-color: #f8d7da;
-    color: #721c24;
-    border: none;
-    padding: 15px 50px;
-    font-size: 18px;
-    font-weight: bold;
-    border-radius: 4px;
-    cursor: pointer;
-}
+    flex-direction: column;
+    align-items: center;
+    padding: 20px;
+  }
+  
+  /* ====================== 响应式适配 ====================== */
+  @media (max-width: 768px) {
+    .table-container,
+    .error-mode-wrap {
+      max-width: 90%;
+    }
+    h1 {
+      font-size: 20px;
+    }
+    th, td {
+      padding: 14px 8px;
+      font-size: 14px;
+    }
+    .btn {
+      padding: 9px 20px;
+    }
+  }
+  
+  @media (max-width: 640px) {
+    .table-container,
+    .error-mode-wrap {
+      max-width: 95%;
+    }
+    h1 {
+      font-size: 18px;
+    }
+    th {
+      padding: 12px 6px;
+      font-size: 12px;
+    }
+    td {
+      padding: 12px 6px;
+      font-size: 13px;
+    }
+    th:nth-child(4), td:nth-child(4) {
+      font-size: 11px;
+    }
+    .btn-group {
+      gap: 10px;
+    }
+    .btn {
+      padding: 8px 16px;
+      font-size: 13px;
+    }
+  }
\ No newline at end of file
diff --git a/frontend/src/home.js b/frontend/src/home.js
deleted file mode 100644 (file)
index 06cdfe5..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import axios from 'axios';
-import './Home.css'; // 我们稍后创建这个样式文件
-
-function Home() {
-    const [progressData, setProgressData] = useState([]);
-    const [showAll, setShowAll] = useState(false);
-    const [stats, setStats] = useState({ pictures_count: 0, words_count: 0 });
-
-    // 获取统计数据和进度数据
-    const fetchData = async () => {
-        try {
-            const resStats = await axios.get('http://124.222.157.124:1060/api/home');
-            setStats(resStats.data);
-
-            const resProcess = await axios.get('http://124.222.157.124:1060/api/home/process');
-            setProgressData(resProcess.data);
-        } catch (error) {
-            console.error("获取数据失败:", error);
-        }
-    };
-
-    useEffect(() => {
-        fetchData();
-        const timer = setInterval(fetchData, 30000); // 30秒自动刷新
-        return () => clearInterval(timer);
-    }, []);
-
-    // 过滤逻辑:模拟 Python 中的 toggle_show_all_groups
-    const filteredData = progressData.filter(item => {
-        if (showAll) return true;
-        // 检查是否所有环节都已完成(包含 ✔️)
-        const isDone = [item.study, item.test, item.review1, item.review2, item.review3]
-            .every(val => val && val.includes('✔️'));
-        return !isDone;
-    });
-
-    // 根据后端返回的文本内容决定样式类
-    const getStatusClass = (text) => {
-        if (!text) return '';
-        if (text.includes('✔️')) return 'status-done';
-        if (text.includes('✅')) return 'status-start';
-        if (text.includes('⚠️')) return 'status-warning';
-        return '';
-    };
-
-    return (
-        <div className="main-app">
-            <header className="header">
-                <h1>单词学习进度记录</h1>
-                <p className="stats-info">
-                    图片总数: {stats.pictures_count} | 单词总数: {stats.words_count}
-                </p>
-            </header>
-
-            <div className="action-bar">
-                <button className="toggle-btn" onClick={() => setShowAll(!showAll)}>
-                    {showAll ? "➖ 隐藏已完成组" : "➕ 显示已完成的组"}
-                </button>
-            </div>
-
-            <div className="table-container">
-                <table className="progress-table">
-                    <thead>
-                        <tr>
-                            <th>组别</th>
-                            <th>基础学习</th>
-                            <th>单元测试</th>
-                            <th>复习 I</th>
-                            <th>复习 II</th>
-                            <th>复习 III</th>
-                        </tr>
-                    </thead>
-                    <tbody>
-                        {filteredData.map((item, index) => (
-                            <tr key={index}>
-                                <td className="group-name">{item.group}</td>
-                                <td className={getStatusClass(item.study)}>{item.study}</td>
-                                <td className={getStatusClass(item.test)}>{item.test}</td>
-                                <td className={getStatusClass(item.review1)}>{item.review1}</td>
-                                <td className={getStatusClass(item.review2)}>{item.review2}</td>
-                                <td className={getStatusClass(item.review3)}>{item.review3}</td>
-                            </tr>
-                        ))}
-                    </tbody>
-                </table>
-            </div>
-
-            <footer className="footer">
-                <button className="error-correction-btn">进入消错模式</button>
-            </footer>
-        </div>
-    );
-}
-
-export default Home;