diff --git a/client/node_modules/.cache/.eslintcache b/client/node_modules/.cache/.eslintcache index 65088909..4d50f6aa 100644 --- a/client/node_modules/.cache/.eslintcache +++ b/client/node_modules/.cache/.eslintcache @@ -1 +1 @@ -[{"D:\\aiproject\\goAgent\\todo\\client\\src\\index.js":"1","D:\\aiproject\\goAgent\\todo\\client\\src\\App.js":"2","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoApp.js":"3","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\LoginForm.js":"4","D:\\aiproject\\goAgent\\todo\\client\\src\\services\\api.js":"5","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoList.js":"6","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoForm.js":"7","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoItem.js":"8","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\HistoryTodos.js":"9","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\SuspendedTodos.js":"10"},{"size":241,"mtime":1749023587387,"results":"11","hashOfConfig":"12"},{"size":1494,"mtime":1749023604385,"results":"13","hashOfConfig":"12"},{"size":10135,"mtime":1749786589011,"results":"14","hashOfConfig":"12"},{"size":2995,"mtime":1749023651380,"results":"15","hashOfConfig":"12"},{"size":2185,"mtime":1749786578050,"results":"16","hashOfConfig":"12"},{"size":1713,"mtime":1749727499219,"results":"17","hashOfConfig":"12"},{"size":4280,"mtime":1749033652041,"results":"18","hashOfConfig":"12"},{"size":5697,"mtime":1749727552702,"results":"19","hashOfConfig":"12"},{"size":4718,"mtime":1749727564696,"results":"20","hashOfConfig":"12"},{"size":7038,"mtime":1749727455449,"results":"21","hashOfConfig":"12"},{"filePath":"22","messages":"23","suppressedMessages":"24","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"1mhfdd",{"filePath":"25","messages":"26","suppressedMessages":"27","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"28","messages":"29","suppressedMessages":"30","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"31","messages":"32","suppressedMessages":"33","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"34","messages":"35","suppressedMessages":"36","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"37","messages":"38","suppressedMessages":"39","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"40","messages":"41","suppressedMessages":"42","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"43","messages":"44","suppressedMessages":"45","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"46","messages":"47","suppressedMessages":"48","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"49","messages":"50","suppressedMessages":"51","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"D:\\aiproject\\goAgent\\todo\\client\\src\\index.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\App.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoApp.js",["52","53"],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\LoginForm.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\services\\api.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoList.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoForm.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoItem.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\HistoryTodos.js",["54"],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\SuspendedTodos.js",[],[],{"ruleId":"55","severity":1,"message":"56","line":3,"column":10,"nodeType":"57","messageId":"58","endLine":3,"endColumn":16},{"ruleId":"55","severity":1,"message":"59","line":196,"column":13,"nodeType":"57","messageId":"58","endLine":196,"endColumn":24},{"ruleId":"55","severity":1,"message":"56","line":3,"column":10,"nodeType":"57","messageId":"58","endLine":3,"endColumn":16},"no-unused-vars","'format' is defined but never used.","Identifier","unusedVar","'updatedTodo' is assigned a value but never used."] \ No newline at end of file +[{"D:\\aiproject\\goAgent\\todo\\client\\src\\index.js":"1","D:\\aiproject\\goAgent\\todo\\client\\src\\App.js":"2","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoApp.js":"3","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\LoginForm.js":"4","D:\\aiproject\\goAgent\\todo\\client\\src\\services\\api.js":"5","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoList.js":"6","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoForm.js":"7","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoItem.js":"8","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\HistoryTodos.js":"9","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\SuspendedTodos.js":"10","D:\\aiproject\\goAgent\\todo\\client\\src\\styles\\theme.js":"11","D:\\aiproject\\goAgent\\todo\\client\\src\\components\\UserManagement.js":"12"},{"size":241,"mtime":1749023587387,"results":"13","hashOfConfig":"14"},{"size":2979,"mtime":1749798864002,"results":"15","hashOfConfig":"14"},{"size":11370,"mtime":1749798959860,"results":"16","hashOfConfig":"14"},{"size":6775,"mtime":1749799161683,"results":"17","hashOfConfig":"14"},{"size":2368,"mtime":1749798814102,"results":"18","hashOfConfig":"14"},{"size":4952,"mtime":1749797292952,"results":"19","hashOfConfig":"14"},{"size":4280,"mtime":1749033652041,"results":"20","hashOfConfig":"14"},{"size":9432,"mtime":1749798048289,"results":"21","hashOfConfig":"14"},{"size":4718,"mtime":1749727564696,"results":"22","hashOfConfig":"14"},{"size":7038,"mtime":1749727455449,"results":"23","hashOfConfig":"14"},{"size":3400,"mtime":1749797186830,"results":"24","hashOfConfig":"14"},{"size":11274,"mtime":1749798908865,"results":"25","hashOfConfig":"14"},{"filePath":"26","messages":"27","suppressedMessages":"28","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"1mhfdd",{"filePath":"29","messages":"30","suppressedMessages":"31","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"32","messages":"33","suppressedMessages":"34","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"35","messages":"36","suppressedMessages":"37","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"38","messages":"39","suppressedMessages":"40","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"41","messages":"42","suppressedMessages":"43","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"44","messages":"45","suppressedMessages":"46","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"47","messages":"48","suppressedMessages":"49","errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"50","messages":"51","suppressedMessages":"52","errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"53","messages":"54","suppressedMessages":"55","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"56","messages":"57","suppressedMessages":"58","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"59","messages":"60","suppressedMessages":"61","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"D:\\aiproject\\goAgent\\todo\\client\\src\\index.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\App.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoApp.js",["62","63"],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\LoginForm.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\services\\api.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoList.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoForm.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\TodoItem.js",["64","65"],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\HistoryTodos.js",["66"],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\SuspendedTodos.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\styles\\theme.js",[],[],"D:\\aiproject\\goAgent\\todo\\client\\src\\components\\UserManagement.js",[],[],{"ruleId":"67","severity":1,"message":"68","line":3,"column":10,"nodeType":"69","messageId":"70","endLine":3,"endColumn":16},{"ruleId":"67","severity":1,"message":"71","line":191,"column":13,"nodeType":"69","messageId":"70","endLine":191,"endColumn":24},{"ruleId":"67","severity":1,"message":"72","line":24,"column":7,"nodeType":"69","messageId":"70","endLine":24,"endColumn":14},{"ruleId":"67","severity":1,"message":"73","line":276,"column":10,"nodeType":"69","messageId":"70","endLine":276,"endColumn":19},{"ruleId":"67","severity":1,"message":"68","line":3,"column":10,"nodeType":"69","messageId":"70","endLine":3,"endColumn":16},"no-unused-vars","'format' is defined but never used.","Identifier","unusedVar","'updatedTodo' is assigned a value but never used.","'scaleIn' is assigned a value but never used.","'isHovered' is assigned a value but never used."] \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/014cccc67358b647f3759a02e8a9c1e6bcbe4be7585ca999da4fa4230892a92c.json b/client/node_modules/.cache/babel-loader/014cccc67358b647f3759a02e8a9c1e6bcbe4be7585ca999da4fa4230892a92c.json new file mode 100644 index 00000000..2495bd5f --- /dev/null +++ b/client/node_modules/.cache/babel-loader/014cccc67358b647f3759a02e8a9c1e6bcbe4be7585ca999da4fa4230892a92c.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\components\\\\UserManagement.js\",\n _s = $RefreshSig$();\nimport React, { useState, useEffect } from 'react';\nimport styled, { keyframes } from 'styled-components';\nimport { getUsers, registerUser } from '../services/api';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst fadeIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\nconst UserManagementContainer = styled.div`\n background: ${({\n theme\n}) => theme.colors.glass.light};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n border-radius: ${({\n theme\n}) => theme.borderRadius.xl};\n padding: ${({\n theme\n}) => theme.spacing.xl};\n box-shadow: ${({\n theme\n}) => theme.shadows.lg};\n border: 1px solid ${({\n theme\n}) => theme.colors.glass.light};\n animation: ${fadeIn} 0.5s ease-out;\n max-width: 800px;\n margin: 0 auto;\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c = UserManagementContainer;\nconst Header = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: ${({\n theme\n}) => theme.spacing.xl};\n padding-bottom: ${({\n theme\n}) => theme.spacing.lg};\n border-bottom: 2px solid ${({\n theme\n}) => theme.colors.glass.light};\n\n @media (prefers-color-scheme: dark) {\n border-bottom-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c2 = Header;\nconst Title = styled.h2`\n color: ${({\n theme\n}) => theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize['2xl']};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.semibold};\n margin: 0;\n display: flex;\n align-items: center;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n\n &::before {\n content: '👥';\n font-size: 1.2em;\n }\n`;\n_c3 = Title;\nconst BackButton = styled.button`\n background: ${({\n theme\n}) => theme.colors.glass.light};\n color: ${({\n theme\n}) => theme.colors.text.primary};\n border: 2px solid ${({\n theme\n}) => theme.colors.glass.light};\n padding: ${({\n theme\n}) => `${theme.spacing.sm} ${theme.spacing.lg}`};\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n cursor: pointer;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n\n &:hover {\n background: ${({\n theme\n}) => theme.colors.primary};\n color: white;\n border-color: ${({\n theme\n}) => theme.colors.primary};\n transform: translateY(-1px);\n }\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c4 = BackButton;\nconst AddUserForm = styled.form`\n display: flex;\n gap: ${({\n theme\n}) => theme.spacing.md};\n margin-bottom: ${({\n theme\n}) => theme.spacing.xl};\n padding: ${({\n theme\n}) => theme.spacing.lg};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n border: 2px dashed ${({\n theme\n}) => theme.colors.primary}40;\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n flex-direction: column;\n }\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c5 = AddUserForm;\nconst InputGroup = styled.div`\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: ${({\n theme\n}) => theme.spacing.xs};\n`;\n_c6 = InputGroup;\nconst Label = styled.label`\n color: ${({\n theme\n}) => theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n`;\n_c7 = Label;\nconst Input = styled.input`\n padding: ${({\n theme\n}) => theme.spacing.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n border: 2px solid ${({\n theme\n}) => theme.colors.glass.light};\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n color: ${({\n theme\n}) => theme.colors.text.primary};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n\n &:focus {\n outline: none;\n border-color: ${({\n theme\n}) => theme.colors.primary};\n box-shadow: 0 0 0 3px ${({\n theme\n}) => theme.colors.primary}40;\n }\n\n &::placeholder {\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n }\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c8 = Input;\nconst AddButton = styled.button`\n background: ${({\n theme\n}) => theme.colors.primary};\n color: white;\n border: none;\n padding: ${({\n theme\n}) => `${theme.spacing.md} ${theme.spacing.lg}`};\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n cursor: pointer;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n align-self: end;\n\n &:hover {\n background: ${({\n theme\n}) => theme.colors.primary}dd;\n transform: translateY(-1px);\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n }\n`;\n_c9 = AddButton;\nconst UserList = styled.div`\n display: flex;\n flex-direction: column;\n gap: ${({\n theme\n}) => theme.spacing.md};\n`;\n_c0 = UserList;\nconst UserItem = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: ${({\n theme\n}) => theme.spacing.lg};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n border: 1px solid ${({\n theme\n}) => theme.colors.glass.light};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n\n &:hover {\n transform: translateY(-1px);\n box-shadow: ${({\n theme\n}) => theme.shadows.md};\n }\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c1 = UserItem;\nconst UserInfo = styled.div`\n display: flex;\n flex-direction: column;\n gap: ${({\n theme\n}) => theme.spacing.xs};\n`;\n_c10 = UserInfo;\nconst Username = styled.span`\n color: ${({\n theme\n}) => theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.lg};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n`;\n_c11 = Username;\nconst UserRole = styled.span`\n color: ${({\n theme,\n isAdmin\n}) => isAdmin ? theme.colors.status.warning : theme.colors.text.secondary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n`;\n_c12 = UserRole;\nconst UserDate = styled.span`\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n`;\n_c13 = UserDate;\nconst Message = styled.div`\n padding: ${({\n theme\n}) => theme.spacing.md};\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n margin-bottom: ${({\n theme\n}) => theme.spacing.lg};\n text-align: center;\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n animation: ${fadeIn} 0.3s ease-out;\n\n ${({\n type,\n theme\n}) => {\n if (type === 'success') {\n return `\n background: ${theme.colors.status.success}20;\n color: ${theme.colors.status.success};\n border: 1px solid ${theme.colors.status.success}40;\n `;\n }\n if (type === 'error') {\n return `\n background: ${theme.colors.status.error}20;\n color: ${theme.colors.status.error};\n border: 1px solid ${theme.colors.status.error}40;\n `;\n }\n return '';\n}}\n`;\n_c14 = Message;\nfunction UserManagement({\n onBack\n}) {\n _s();\n const [users, setUsers] = useState([]);\n const [username, setUsername] = useState('');\n const [password, setPassword] = useState('');\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [message, setMessage] = useState({\n text: '',\n type: ''\n });\n useEffect(() => {\n loadUsers();\n }, []);\n const loadUsers = async () => {\n try {\n setLoading(true);\n const userData = await getUsers();\n setUsers(userData);\n } catch (error) {\n setMessage({\n text: '加载用户列表失败',\n type: 'error'\n });\n } finally {\n setLoading(false);\n }\n };\n const handleSubmit = async e => {\n e.preventDefault();\n if (!username.trim() || !password.trim()) {\n setMessage({\n text: '用户名和密码不能为空',\n type: 'error'\n });\n return;\n }\n setSubmitting(true);\n try {\n await registerUser(username.trim(), password);\n setMessage({\n text: '用户添加成功',\n type: 'success'\n });\n setUsername('');\n setPassword('');\n await loadUsers();\n } catch (error) {\n var _error$response, _error$response$data;\n setMessage({\n text: ((_error$response = error.response) === null || _error$response === void 0 ? void 0 : (_error$response$data = _error$response.data) === null || _error$response$data === void 0 ? void 0 : _error$response$data.error) || '添加用户失败',\n type: 'error'\n });\n } finally {\n setSubmitting(false);\n }\n\n // 清除消息\n setTimeout(() => setMessage({\n text: '',\n type: ''\n }), 5000);\n };\n const formatDate = dateString => {\n return new Date(dateString).toLocaleDateString('zh-CN', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n });\n };\n return /*#__PURE__*/_jsxDEV(UserManagementContainer, {\n children: [/*#__PURE__*/_jsxDEV(Header, {\n children: [/*#__PURE__*/_jsxDEV(Title, {\n children: \"\\u7528\\u6237\\u7BA1\\u7406\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 306,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(BackButton, {\n onClick: onBack,\n children: \"\\u8FD4\\u56DE\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 307,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 305,\n columnNumber: 7\n }, this), message.text && /*#__PURE__*/_jsxDEV(Message, {\n type: message.type,\n children: message.text\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 311,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(AddUserForm, {\n onSubmit: handleSubmit,\n children: [/*#__PURE__*/_jsxDEV(InputGroup, {\n children: [/*#__PURE__*/_jsxDEV(Label, {\n children: \"\\u7528\\u6237\\u540D\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 316,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(Input, {\n type: \"text\",\n placeholder: \"\\u8BF7\\u8F93\\u5165\\u7528\\u6237\\u540D\",\n value: username,\n onChange: e => setUsername(e.target.value),\n disabled: submitting,\n required: true\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 317,\n columnNumber: 11\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 315,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(InputGroup, {\n children: [/*#__PURE__*/_jsxDEV(Label, {\n children: \"\\u5BC6\\u7801\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 327,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(Input, {\n type: \"password\",\n placeholder: \"\\u8BF7\\u8F93\\u5165\\u5BC6\\u7801\",\n value: password,\n onChange: e => setPassword(e.target.value),\n disabled: submitting,\n required: true\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 328,\n columnNumber: 11\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 326,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(AddButton, {\n type: \"submit\",\n disabled: submitting,\n children: submitting ? '添加中...' : '添加用户'\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 337,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 314,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(UserList, {\n children: loading ? /*#__PURE__*/_jsxDEV(\"div\", {\n style: {\n textAlign: 'center',\n padding: '2rem'\n },\n children: \"\\u52A0\\u8F7D\\u4E2D...\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 344,\n columnNumber: 11\n }, this) : users.length === 0 ? /*#__PURE__*/_jsxDEV(\"div\", {\n style: {\n textAlign: 'center',\n padding: '2rem',\n color: '#999'\n },\n children: \"\\u6682\\u65E0\\u7528\\u6237\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 348,\n columnNumber: 11\n }, this) : users.map(user => /*#__PURE__*/_jsxDEV(UserItem, {\n children: /*#__PURE__*/_jsxDEV(UserInfo, {\n children: [/*#__PURE__*/_jsxDEV(Username, {\n children: user.username\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 355,\n columnNumber: 17\n }, this), /*#__PURE__*/_jsxDEV(UserRole, {\n isAdmin: user.is_admin,\n children: user.is_admin ? '管理员' : '普通用户'\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 356,\n columnNumber: 17\n }, this), /*#__PURE__*/_jsxDEV(UserDate, {\n children: [\"\\u521B\\u5EFA\\u4E8E \", formatDate(user.created_at)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 359,\n columnNumber: 17\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 354,\n columnNumber: 15\n }, this)\n }, user.id, false, {\n fileName: _jsxFileName,\n lineNumber: 353,\n columnNumber: 13\n }, this))\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 342,\n columnNumber: 7\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 304,\n columnNumber: 5\n }, this);\n}\n_s(UserManagement, \"kD1DilUl1pPd4G+q3+6hMBaCtxw=\");\n_c15 = UserManagement;\nexport default UserManagement;\nvar _c, _c2, _c3, _c4, _c5, _c6, _c7, _c8, _c9, _c0, _c1, _c10, _c11, _c12, _c13, _c14, _c15;\n$RefreshReg$(_c, \"UserManagementContainer\");\n$RefreshReg$(_c2, \"Header\");\n$RefreshReg$(_c3, \"Title\");\n$RefreshReg$(_c4, \"BackButton\");\n$RefreshReg$(_c5, \"AddUserForm\");\n$RefreshReg$(_c6, \"InputGroup\");\n$RefreshReg$(_c7, \"Label\");\n$RefreshReg$(_c8, \"Input\");\n$RefreshReg$(_c9, \"AddButton\");\n$RefreshReg$(_c0, \"UserList\");\n$RefreshReg$(_c1, \"UserItem\");\n$RefreshReg$(_c10, \"UserInfo\");\n$RefreshReg$(_c11, \"Username\");\n$RefreshReg$(_c12, \"UserRole\");\n$RefreshReg$(_c13, \"UserDate\");\n$RefreshReg$(_c14, \"Message\");\n$RefreshReg$(_c15, \"UserManagement\");","map":{"version":3,"names":["React","useState","useEffect","styled","keyframes","getUsers","registerUser","jsxDEV","_jsxDEV","fadeIn","UserManagementContainer","div","theme","colors","glass","light","borderRadius","xl","spacing","shadows","lg","dark","_c","Header","_c2","Title","h2","text","primary","typography","fontSize","fontWeight","semibold","sm","_c3","BackButton","button","transitions","default","_c4","AddUserForm","form","md","breakpoints","_c5","InputGroup","xs","_c6","Label","label","medium","_c7","Input","input","base","secondary","_c8","AddButton","_c9","UserList","_c0","UserItem","_c1","UserInfo","_c10","Username","span","_c11","UserRole","isAdmin","status","warning","_c12","UserDate","_c13","Message","type","success","error","_c14","UserManagement","onBack","_s","users","setUsers","username","setUsername","password","setPassword","loading","setLoading","submitting","setSubmitting","message","setMessage","loadUsers","userData","handleSubmit","e","preventDefault","trim","_error$response","_error$response$data","response","data","setTimeout","formatDate","dateString","Date","toLocaleDateString","year","month","day","hour","minute","children","fileName","_jsxFileName","lineNumber","columnNumber","onClick","onSubmit","placeholder","value","onChange","target","disabled","required","style","textAlign","padding","length","color","map","user","is_admin","created_at","id","_c15","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/components/UserManagement.js"],"sourcesContent":["import React, { useState, useEffect } from 'react';\r\nimport styled, { keyframes } from 'styled-components';\r\nimport { getUsers, registerUser } from '../services/api';\r\n\r\nconst fadeIn = keyframes`\r\n from {\r\n opacity: 0;\r\n transform: translateY(20px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n`;\r\n\r\nconst UserManagementContainer = styled.div`\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: ${({ theme }) => theme.borderRadius.xl};\r\n padding: ${({ theme }) => theme.spacing.xl};\r\n box-shadow: ${({ theme }) => theme.shadows.lg};\r\n border: 1px solid ${({ theme }) => theme.colors.glass.light};\r\n animation: ${fadeIn} 0.5s ease-out;\r\n max-width: 800px;\r\n margin: 0 auto;\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst Header = styled.div`\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: ${({ theme }) => theme.spacing.xl};\r\n padding-bottom: ${({ theme }) => theme.spacing.lg};\r\n border-bottom: 2px solid ${({ theme }) => theme.colors.glass.light};\r\n\r\n @media (prefers-color-scheme: dark) {\r\n border-bottom-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst Title = styled.h2`\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize['2xl']};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};\r\n margin: 0;\r\n display: flex;\r\n align-items: center;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n\r\n &::before {\r\n content: '👥';\r\n font-size: 1.2em;\r\n }\r\n`;\r\n\r\nconst BackButton = styled.button`\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n border: 2px solid ${({ theme }) => theme.colors.glass.light};\r\n padding: ${({ theme }) => `${theme.spacing.sm} ${theme.spacing.lg}`};\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n cursor: pointer;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.primary};\r\n color: white;\r\n border-color: ${({ theme }) => theme.colors.primary};\r\n transform: translateY(-1px);\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst AddUserForm = styled.form`\r\n display: flex;\r\n gap: ${({ theme }) => theme.spacing.md};\r\n margin-bottom: ${({ theme }) => theme.spacing.xl};\r\n padding: ${({ theme }) => theme.spacing.lg};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n border: 2px dashed ${({ theme }) => theme.colors.primary}40;\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n flex-direction: column;\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst InputGroup = styled.div`\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: ${({ theme }) => theme.spacing.xs};\r\n`;\r\n\r\nconst Label = styled.label`\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n`;\r\n\r\nconst Input = styled.input`\r\n padding: ${({ theme }) => theme.spacing.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n border: 2px solid ${({ theme }) => theme.colors.glass.light};\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n\r\n &:focus {\r\n outline: none;\r\n border-color: ${({ theme }) => theme.colors.primary};\r\n box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40;\r\n }\r\n\r\n &::placeholder {\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst AddButton = styled.button`\r\n background: ${({ theme }) => theme.colors.primary};\r\n color: white;\r\n border: none;\r\n padding: ${({ theme }) => `${theme.spacing.md} ${theme.spacing.lg}`};\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n cursor: pointer;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n align-self: end;\r\n\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.primary}dd;\r\n transform: translateY(-1px);\r\n }\r\n\r\n &:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n transform: none;\r\n }\r\n`;\r\n\r\nconst UserList = styled.div`\r\n display: flex;\r\n flex-direction: column;\r\n gap: ${({ theme }) => theme.spacing.md};\r\n`;\r\n\r\nconst UserItem = styled.div`\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: ${({ theme }) => theme.spacing.lg};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n border: 1px solid ${({ theme }) => theme.colors.glass.light};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n\r\n &:hover {\r\n transform: translateY(-1px);\r\n box-shadow: ${({ theme }) => theme.shadows.md};\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst UserInfo = styled.div`\r\n display: flex;\r\n flex-direction: column;\r\n gap: ${({ theme }) => theme.spacing.xs};\r\n`;\r\n\r\nconst Username = styled.span`\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.lg};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n`;\r\n\r\nconst UserRole = styled.span`\r\n color: ${({ theme, isAdmin }) => isAdmin ? theme.colors.status.warning : theme.colors.text.secondary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n`;\r\n\r\nconst UserDate = styled.span`\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n`;\r\n\r\nconst Message = styled.div`\r\n padding: ${({ theme }) => theme.spacing.md};\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n margin-bottom: ${({ theme }) => theme.spacing.lg};\r\n text-align: center;\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n animation: ${fadeIn} 0.3s ease-out;\r\n\r\n ${({ type, theme }) => {\r\n if (type === 'success') {\r\n return `\r\n background: ${theme.colors.status.success}20;\r\n color: ${theme.colors.status.success};\r\n border: 1px solid ${theme.colors.status.success}40;\r\n `;\r\n }\r\n if (type === 'error') {\r\n return `\r\n background: ${theme.colors.status.error}20;\r\n color: ${theme.colors.status.error};\r\n border: 1px solid ${theme.colors.status.error}40;\r\n `;\r\n }\r\n return '';\r\n }}\r\n`;\r\n\r\nfunction UserManagement({ onBack }) {\r\n const [users, setUsers] = useState([]);\r\n const [username, setUsername] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [loading, setLoading] = useState(true);\r\n const [submitting, setSubmitting] = useState(false);\r\n const [message, setMessage] = useState({ text: '', type: '' });\r\n\r\n useEffect(() => {\r\n loadUsers();\r\n }, []);\r\n\r\n const loadUsers = async () => {\r\n try {\r\n setLoading(true);\r\n const userData = await getUsers();\r\n setUsers(userData);\r\n } catch (error) {\r\n setMessage({ text: '加载用户列表失败', type: 'error' });\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n const handleSubmit = async (e) => {\r\n e.preventDefault();\r\n if (!username.trim() || !password.trim()) {\r\n setMessage({ text: '用户名和密码不能为空', type: 'error' });\r\n return;\r\n }\r\n\r\n setSubmitting(true);\r\n try {\r\n await registerUser(username.trim(), password);\r\n setMessage({ text: '用户添加成功', type: 'success' });\r\n setUsername('');\r\n setPassword('');\r\n await loadUsers();\r\n } catch (error) {\r\n setMessage({ \r\n text: error.response?.data?.error || '添加用户失败', \r\n type: 'error' \r\n });\r\n } finally {\r\n setSubmitting(false);\r\n }\r\n\r\n // 清除消息\r\n setTimeout(() => setMessage({ text: '', type: '' }), 5000);\r\n };\r\n\r\n const formatDate = (dateString) => {\r\n return new Date(dateString).toLocaleDateString('zh-CN', {\r\n year: 'numeric',\r\n month: 'short',\r\n day: 'numeric',\r\n hour: '2-digit',\r\n minute: '2-digit'\r\n });\r\n };\r\n\r\n return (\r\n \r\n
\r\n 用户管理\r\n 返回\r\n
\r\n\r\n {message.text && (\r\n {message.text}\r\n )}\r\n\r\n \r\n \r\n \r\n setUsername(e.target.value)}\r\n disabled={submitting}\r\n required\r\n />\r\n \r\n \r\n \r\n setPassword(e.target.value)}\r\n disabled={submitting}\r\n required\r\n />\r\n \r\n \r\n {submitting ? '添加中...' : '添加用户'}\r\n \r\n \r\n\r\n \r\n {loading ? (\r\n
\r\n 加载中...\r\n
\r\n ) : users.length === 0 ? (\r\n
\r\n 暂无用户\r\n
\r\n ) : (\r\n users.map(user => (\r\n \r\n \r\n {user.username}\r\n \r\n {user.is_admin ? '管理员' : '普通用户'}\r\n \r\n 创建于 {formatDate(user.created_at)}\r\n \r\n \r\n ))\r\n )}\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default UserManagement; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/0300b30013d15f14abe42de07b449562a4f0280bcdc54b047ac5c9c7521a0e9d.json b/client/node_modules/.cache/babel-loader/0300b30013d15f14abe42de07b449562a4f0280bcdc54b047ac5c9c7521a0e9d.json new file mode 100644 index 00000000..b5f4d72b --- /dev/null +++ b/client/node_modules/.cache/babel-loader/0300b30013d15f14abe42de07b449562a4f0280bcdc54b047ac5c9c7521a0e9d.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\components\\\\TodoItem.js\",\n _s = $RefreshSig$();\nimport React, { useState } from 'react';\nimport styled, { keyframes } from 'styled-components';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst slideIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(-10px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\nconst fadeIn = keyframes`\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n`;\nconst scaleIn = keyframes`\n from {\n transform: scale(0.95);\n }\n to {\n transform: scale(1);\n }\n`;\nconst ItemContainer = styled.div`\n background: ${({\n theme\n}) => theme.colors.glass.light};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n padding: ${({\n theme\n}) => theme.spacing.lg};\n display: flex;\n align-items: center;\n gap: ${({\n theme\n}) => theme.spacing.md};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n border: 1px solid ${({\n theme\n}) => theme.colors.glass.light};\n animation: ${slideIn} 0.3s ease-out;\n position: relative;\n overflow: hidden;\n cursor: pointer;\n\n &:hover {\n transform: translateY(-2px);\n box-shadow: ${({\n theme\n}) => theme.shadows.md};\n }\n\n &:active {\n transform: translateY(0);\n box-shadow: ${({\n theme\n}) => theme.shadows.sm};\n }\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n padding: ${({\n theme\n}) => theme.spacing.md};\n }\n`;\n_c = ItemContainer;\nconst Checkbox = styled.input`\n appearance: none;\n width: 24px;\n height: 24px;\n border: 2px solid ${({\n theme\n}) => theme.colors.primary};\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n cursor: pointer;\n position: relative;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n flex-shrink: 0;\n\n &:checked {\n background: ${({\n theme\n}) => theme.colors.primary};\n border-color: ${({\n theme\n}) => theme.colors.primary};\n }\n\n &:checked::after {\n content: '✓';\n position: absolute;\n color: white;\n font-size: 16px;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n animation: ${fadeIn} 0.2s ease-out;\n }\n\n &:hover {\n transform: scale(1.1);\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 3px ${({\n theme\n}) => theme.colors.primary}40;\n }\n`;\n_c2 = Checkbox;\nconst Content = styled.div`\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: ${({\n theme\n}) => theme.spacing.xs};\n min-width: 0; // 防止内容溢出\n`;\n_c3 = Content;\nconst Title = styled.span`\n color: ${({\n theme,\n completed\n}) => completed ? theme.colors.text.secondary : theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n text-decoration: ${({\n completed\n}) => completed ? 'line-through' : 'none'};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n_c4 = Title;\nconst Description = styled.p`\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n margin: 0;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n`;\n_c5 = Description;\nconst PriorityBadge = styled.span`\n padding: ${({\n theme\n}) => `${theme.spacing.xs} ${theme.spacing.sm}`};\n border-radius: ${({\n theme\n}) => theme.borderRadius.full};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.xs};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n background: ${({\n theme,\n priority\n}) => theme.colors.priority[priority]}20;\n color: ${({\n theme,\n priority\n}) => theme.colors.priority[priority]};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n display: inline-flex;\n align-items: center;\n gap: ${({\n theme\n}) => theme.spacing.xs};\n\n &::before {\n content: ${({\n priority\n}) => {\n switch (priority) {\n case 'urgent':\n return '\"🚨\"';\n case 'high':\n return '\"🔥\"';\n case 'medium':\n return '\"⚡\"';\n case 'low':\n return '\"🐢\"';\n default:\n return '\"📌\"';\n }\n}};\n font-size: 1.1em;\n }\n\n &:hover {\n transform: translateY(-1px);\n background: ${({\n theme,\n priority\n}) => theme.colors.priority[priority]}30;\n }\n`;\n_c6 = PriorityBadge;\nconst ButtonGroup = styled.div`\n display: flex;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n opacity: 0;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n position: absolute;\n right: ${({\n theme\n}) => theme.spacing.lg};\n top: 50%;\n transform: translateY(-50%);\n\n ${ItemContainer}:hover & {\n opacity: 1;\n }\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n opacity: 1;\n position: static;\n transform: none;\n }\n`;\n_c7 = ButtonGroup;\nconst ActionButton = styled.button`\n background: none;\n border: none;\n padding: ${({\n theme\n}) => theme.spacing.sm};\n cursor: pointer;\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.2em;\n\n &:hover {\n background: ${({\n theme\n}) => theme.colors.glass.light};\n color: ${({\n theme\n}) => theme.colors.primary};\n transform: translateY(-1px);\n }\n\n &:active {\n transform: translateY(0);\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 3px ${({\n theme\n}) => theme.colors.primary}40;\n }\n\n @media (prefers-color-scheme: dark) {\n &:hover {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n }\n`;\n_c8 = ActionButton;\nconst StatusBadge = styled.span`\n position: absolute;\n top: ${({\n theme\n}) => theme.spacing.sm};\n right: ${({\n theme\n}) => theme.spacing.sm};\n padding: ${({\n theme\n}) => `${theme.spacing.xs} ${theme.spacing.sm}`};\n border-radius: ${({\n theme\n}) => theme.borderRadius.full};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.xs};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n background: ${({\n theme,\n status\n}) => theme.colors.status[status]}20;\n color: ${({\n theme,\n status\n}) => theme.colors.status[status]};\n animation: ${fadeIn} 0.3s ease-out;\n display: flex;\n align-items: center;\n gap: ${({\n theme\n}) => theme.spacing.xs};\n\n &::before {\n content: ${({\n status\n}) => {\n switch (status) {\n case 'warning':\n return '\"⏸️\"';\n case 'success':\n return '\"✅\"';\n case 'error':\n return '\"❌\"';\n default:\n return '\"📌\"';\n }\n}};\n font-size: 1.1em;\n }\n`;\n_c9 = StatusBadge;\nconst Tooltip = styled.div`\n position: absolute;\n bottom: 100%;\n left: 50%;\n transform: translateX(-50%);\n padding: ${({\n theme\n}) => `${theme.spacing.xs} ${theme.spacing.sm}`};\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n color: ${({\n theme\n}) => theme.colors.text.light};\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.xs};\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n pointer-events: none;\n z-index: 1000;\n\n ${ActionButton}:hover & {\n opacity: 1;\n visibility: visible;\n transform: translateX(-50%) translateY(-4px);\n }\n`;\n_c0 = Tooltip;\nfunction TodoItem({\n todo,\n onToggle,\n onDelete,\n onSuspend,\n isHistory,\n isToday\n}) {\n _s();\n const [isHovered, setIsHovered] = useState(false);\n const getPriorityLabel = priority => {\n const labels = {\n low: '低优先级',\n medium: '中优先级',\n high: '高优先级',\n urgent: '紧急'\n };\n return labels[priority] || priority;\n };\n const handleToggle = e => {\n e.stopPropagation();\n onToggle(todo.id);\n };\n const handleDelete = e => {\n e.stopPropagation();\n onDelete(todo.id);\n };\n const handleSuspend = e => {\n e.stopPropagation();\n onSuspend(todo.id);\n };\n return /*#__PURE__*/_jsxDEV(ItemContainer, {\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: () => setIsHovered(false),\n onClick: handleToggle,\n children: [/*#__PURE__*/_jsxDEV(Checkbox, {\n type: \"checkbox\",\n checked: todo.completed,\n onChange: handleToggle\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 309,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(Content, {\n children: [/*#__PURE__*/_jsxDEV(Title, {\n completed: todo.completed,\n children: todo.title\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 315,\n columnNumber: 9\n }, this), todo.description && /*#__PURE__*/_jsxDEV(Description, {\n children: todo.description\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 319,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(PriorityBadge, {\n priority: todo.priority,\n children: getPriorityLabel(todo.priority)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 321,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 314,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(ButtonGroup, {\n children: [isToday && !todo.completed && !todo.suspended && /*#__PURE__*/_jsxDEV(ActionButton, {\n onClick: handleSuspend,\n title: \"\\u6302\\u8D77\",\n children: [\"\\u23F8\\uFE0F\", /*#__PURE__*/_jsxDEV(Tooltip, {\n children: \"\\u6302\\u8D77\\u4EFB\\u52A1\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 329,\n columnNumber: 13\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 327,\n columnNumber: 11\n }, this), !isHistory && /*#__PURE__*/_jsxDEV(ActionButton, {\n onClick: handleDelete,\n title: \"\\u5220\\u9664\",\n children: [\"\\uD83D\\uDDD1\\uFE0F\", /*#__PURE__*/_jsxDEV(Tooltip, {\n children: \"\\u5220\\u9664\\u4EFB\\u52A1\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 335,\n columnNumber: 13\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 333,\n columnNumber: 11\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 325,\n columnNumber: 7\n }, this), todo.suspended && /*#__PURE__*/_jsxDEV(StatusBadge, {\n status: \"warning\",\n children: \"\\u5DF2\\u6302\\u8D77\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 340,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 304,\n columnNumber: 5\n }, this);\n}\n_s(TodoItem, \"FPQn8a98tPjpohC7NUYORQR8GJE=\");\n_c1 = TodoItem;\nexport default TodoItem;\nvar _c, _c2, _c3, _c4, _c5, _c6, _c7, _c8, _c9, _c0, _c1;\n$RefreshReg$(_c, \"ItemContainer\");\n$RefreshReg$(_c2, \"Checkbox\");\n$RefreshReg$(_c3, \"Content\");\n$RefreshReg$(_c4, \"Title\");\n$RefreshReg$(_c5, \"Description\");\n$RefreshReg$(_c6, \"PriorityBadge\");\n$RefreshReg$(_c7, \"ButtonGroup\");\n$RefreshReg$(_c8, \"ActionButton\");\n$RefreshReg$(_c9, \"StatusBadge\");\n$RefreshReg$(_c0, \"Tooltip\");\n$RefreshReg$(_c1, \"TodoItem\");","map":{"version":3,"names":["React","useState","styled","keyframes","jsxDEV","_jsxDEV","slideIn","fadeIn","scaleIn","ItemContainer","div","theme","colors","glass","light","borderRadius","lg","spacing","md","transitions","default","shadows","sm","dark","breakpoints","_c","Checkbox","input","primary","_c2","Content","xs","_c3","Title","span","completed","text","secondary","typography","fontSize","base","fontWeight","medium","_c4","Description","p","_c5","PriorityBadge","full","priority","_c6","ButtonGroup","_c7","ActionButton","button","_c8","StatusBadge","status","_c9","Tooltip","_c0","TodoItem","todo","onToggle","onDelete","onSuspend","isHistory","isToday","_s","isHovered","setIsHovered","getPriorityLabel","labels","low","high","urgent","handleToggle","e","stopPropagation","id","handleDelete","handleSuspend","onMouseEnter","onMouseLeave","onClick","children","type","checked","onChange","fileName","_jsxFileName","lineNumber","columnNumber","title","description","suspended","_c1","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/components/TodoItem.js"],"sourcesContent":["import React, { useState } from 'react';\r\nimport styled, { keyframes } from 'styled-components';\r\n\r\nconst slideIn = keyframes`\r\n from {\r\n opacity: 0;\r\n transform: translateX(-10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0);\r\n }\r\n`;\r\n\r\nconst fadeIn = keyframes`\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n`;\r\n\r\nconst scaleIn = keyframes`\r\n from {\r\n transform: scale(0.95);\r\n }\r\n to {\r\n transform: scale(1);\r\n }\r\n`;\r\n\r\nconst ItemContainer = styled.div`\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n padding: ${({ theme }) => theme.spacing.lg};\r\n display: flex;\r\n align-items: center;\r\n gap: ${({ theme }) => theme.spacing.md};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n border: 1px solid ${({ theme }) => theme.colors.glass.light};\r\n animation: ${slideIn} 0.3s ease-out;\r\n position: relative;\r\n overflow: hidden;\r\n cursor: pointer;\r\n\r\n &:hover {\r\n transform: translateY(-2px);\r\n box-shadow: ${({ theme }) => theme.shadows.md};\r\n }\r\n\r\n &:active {\r\n transform: translateY(0);\r\n box-shadow: ${({ theme }) => theme.shadows.sm};\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n padding: ${({ theme }) => theme.spacing.md};\r\n }\r\n`;\r\n\r\nconst Checkbox = styled.input`\r\n appearance: none;\r\n width: 24px;\r\n height: 24px;\r\n border: 2px solid ${({ theme }) => theme.colors.primary};\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n cursor: pointer;\r\n position: relative;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n flex-shrink: 0;\r\n\r\n &:checked {\r\n background: ${({ theme }) => theme.colors.primary};\r\n border-color: ${({ theme }) => theme.colors.primary};\r\n }\r\n\r\n &:checked::after {\r\n content: '✓';\r\n position: absolute;\r\n color: white;\r\n font-size: 16px;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n animation: ${fadeIn} 0.2s ease-out;\r\n }\r\n\r\n &:hover {\r\n transform: scale(1.1);\r\n }\r\n\r\n &:focus {\r\n outline: none;\r\n box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40;\r\n }\r\n`;\r\n\r\nconst Content = styled.div`\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: ${({ theme }) => theme.spacing.xs};\r\n min-width: 0; // 防止内容溢出\r\n`;\r\n\r\nconst Title = styled.span`\r\n color: ${({ theme, completed }) => completed ? theme.colors.text.secondary : theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n text-decoration: ${({ completed }) => completed ? 'line-through' : 'none'};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n`;\r\n\r\nconst Description = styled.p`\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n line-height: 1.4;\r\n`;\r\n\r\nconst PriorityBadge = styled.span`\r\n padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.sm}`};\r\n border-radius: ${({ theme }) => theme.borderRadius.full};\r\n font-size: ${({ theme }) => theme.typography.fontSize.xs};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n background: ${({ theme, priority }) => theme.colors.priority[priority]}20;\r\n color: ${({ theme, priority }) => theme.colors.priority[priority]};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n display: inline-flex;\r\n align-items: center;\r\n gap: ${({ theme }) => theme.spacing.xs};\r\n\r\n &::before {\r\n content: ${({ priority }) => {\r\n switch (priority) {\r\n case 'urgent': return '\"🚨\"';\r\n case 'high': return '\"🔥\"';\r\n case 'medium': return '\"⚡\"';\r\n case 'low': return '\"🐢\"';\r\n default: return '\"📌\"';\r\n }\r\n }};\r\n font-size: 1.1em;\r\n }\r\n\r\n &:hover {\r\n transform: translateY(-1px);\r\n background: ${({ theme, priority }) => theme.colors.priority[priority]}30;\r\n }\r\n`;\r\n\r\nconst ButtonGroup = styled.div`\r\n display: flex;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n opacity: 0;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n position: absolute;\r\n right: ${({ theme }) => theme.spacing.lg};\r\n top: 50%;\r\n transform: translateY(-50%);\r\n\r\n ${ItemContainer}:hover & {\r\n opacity: 1;\r\n }\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n opacity: 1;\r\n position: static;\r\n transform: none;\r\n }\r\n`;\r\n\r\nconst ActionButton = styled.button`\r\n background: none;\r\n border: none;\r\n padding: ${({ theme }) => theme.spacing.sm};\r\n cursor: pointer;\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 1.2em;\r\n\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n color: ${({ theme }) => theme.colors.primary};\r\n transform: translateY(-1px);\r\n }\r\n\r\n &:active {\r\n transform: translateY(0);\r\n }\r\n\r\n &:focus {\r\n outline: none;\r\n box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40;\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n }\r\n`;\r\n\r\nconst StatusBadge = styled.span`\r\n position: absolute;\r\n top: ${({ theme }) => theme.spacing.sm};\r\n right: ${({ theme }) => theme.spacing.sm};\r\n padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.sm}`};\r\n border-radius: ${({ theme }) => theme.borderRadius.full};\r\n font-size: ${({ theme }) => theme.typography.fontSize.xs};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n background: ${({ theme, status }) => theme.colors.status[status]}20;\r\n color: ${({ theme, status }) => theme.colors.status[status]};\r\n animation: ${fadeIn} 0.3s ease-out;\r\n display: flex;\r\n align-items: center;\r\n gap: ${({ theme }) => theme.spacing.xs};\r\n\r\n &::before {\r\n content: ${({ status }) => {\r\n switch (status) {\r\n case 'warning': return '\"⏸️\"';\r\n case 'success': return '\"✅\"';\r\n case 'error': return '\"❌\"';\r\n default: return '\"📌\"';\r\n }\r\n }};\r\n font-size: 1.1em;\r\n }\r\n`;\r\n\r\nconst Tooltip = styled.div`\r\n position: absolute;\r\n bottom: 100%;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.sm}`};\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n color: ${({ theme }) => theme.colors.text.light};\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.xs};\r\n white-space: nowrap;\r\n opacity: 0;\r\n visibility: hidden;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n pointer-events: none;\r\n z-index: 1000;\r\n\r\n ${ActionButton}:hover & {\r\n opacity: 1;\r\n visibility: visible;\r\n transform: translateX(-50%) translateY(-4px);\r\n }\r\n`;\r\n\r\nfunction TodoItem({ todo, onToggle, onDelete, onSuspend, isHistory, isToday }) {\r\n const [isHovered, setIsHovered] = useState(false);\r\n\r\n const getPriorityLabel = (priority) => {\r\n const labels = {\r\n low: '低优先级',\r\n medium: '中优先级',\r\n high: '高优先级',\r\n urgent: '紧急'\r\n };\r\n return labels[priority] || priority;\r\n };\r\n\r\n const handleToggle = (e) => {\r\n e.stopPropagation();\r\n onToggle(todo.id);\r\n };\r\n\r\n const handleDelete = (e) => {\r\n e.stopPropagation();\r\n onDelete(todo.id);\r\n };\r\n\r\n const handleSuspend = (e) => {\r\n e.stopPropagation();\r\n onSuspend(todo.id);\r\n };\r\n\r\n return (\r\n setIsHovered(true)}\r\n onMouseLeave={() => setIsHovered(false)}\r\n onClick={handleToggle}\r\n >\r\n \r\n \r\n \r\n {todo.title}\r\n \r\n {todo.description && (\r\n {todo.description}\r\n )}\r\n \r\n {getPriorityLabel(todo.priority)}\r\n \r\n \r\n \r\n {isToday && !todo.completed && !todo.suspended && (\r\n \r\n ⏸️\r\n 挂起任务\r\n \r\n )}\r\n {!isHistory && (\r\n \r\n 🗑️\r\n 删除任务\r\n \r\n )}\r\n \r\n {todo.suspended && (\r\n 已挂起\r\n )}\r\n \r\n );\r\n}\r\n\r\nexport default TodoItem; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/0cd906f553e1ef5e294ac472729e70437f21530386f7a28421428b2e7ae5ac6b.json b/client/node_modules/.cache/babel-loader/0cd906f553e1ef5e294ac472729e70437f21530386f7a28421428b2e7ae5ac6b.json new file mode 100644 index 00000000..8df2a222 --- /dev/null +++ b/client/node_modules/.cache/babel-loader/0cd906f553e1ef5e294ac472729e70437f21530386f7a28421428b2e7ae5ac6b.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\App.js\",\n _s = $RefreshSig$();\nimport React, { useState, useEffect } from 'react';\nimport { ThemeProvider } from 'styled-components';\nimport { theme, GlobalStyle } from './styles/theme';\nimport LoginForm from './components/LoginForm';\nimport TodoApp from './components/TodoApp';\nimport styled from 'styled-components';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst AppContainer = styled.div`\n min-height: 100vh;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: ${({\n theme\n}) => theme.spacing.md};\n background: linear-gradient(135deg, ${({\n theme\n}) => theme.colors.primary}20, ${({\n theme\n}) => theme.colors.secondary}20);\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n padding: ${({\n theme\n}) => theme.spacing.sm};\n }\n`;\n_c = AppContainer;\nconst AppContent = styled.div`\n width: 100%;\n max-width: 1200px;\n height: 100%;\n min-height: 600px;\n display: flex;\n flex-direction: column;\n position: relative;\n`;\n_c2 = AppContent;\nfunction App() {\n _s();\n const [isAuthenticated, setIsAuthenticated] = useState(false);\n const [isLoading, setIsLoading] = useState(true);\n useEffect(() => {\n const token = localStorage.getItem('token');\n if (token) {\n setIsAuthenticated(true);\n }\n setIsLoading(false);\n }, []);\n const handleLogin = token => {\n localStorage.setItem('token', token);\n setIsAuthenticated(true);\n };\n const handleLogout = () => {\n localStorage.removeItem('token');\n setIsAuthenticated(false);\n };\n if (isLoading) {\n return /*#__PURE__*/_jsxDEV(ThemeProvider, {\n theme: theme,\n children: [/*#__PURE__*/_jsxDEV(GlobalStyle, {}, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 58,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(AppContainer, {\n children: /*#__PURE__*/_jsxDEV(AppContent, {\n children: /*#__PURE__*/_jsxDEV(\"div\", {\n style: {\n textAlign: 'center',\n color: theme.colors.text.secondary\n },\n children: \"\\u52A0\\u8F7D\\u4E2D...\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 61,\n columnNumber: 13\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 60,\n columnNumber: 11\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 59,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 57,\n columnNumber: 7\n }, this);\n }\n return /*#__PURE__*/_jsxDEV(ThemeProvider, {\n theme: theme,\n children: [/*#__PURE__*/_jsxDEV(GlobalStyle, {}, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 72,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(AppContainer, {\n children: /*#__PURE__*/_jsxDEV(AppContent, {\n children: isAuthenticated ? /*#__PURE__*/_jsxDEV(TodoApp, {\n onLogout: handleLogout\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 76,\n columnNumber: 13\n }, this) : /*#__PURE__*/_jsxDEV(LoginForm, {\n onLogin: handleLogin\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 78,\n columnNumber: 13\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 74,\n columnNumber: 9\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 73,\n columnNumber: 7\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 71,\n columnNumber: 5\n }, this);\n}\n_s(App, \"QGOAXroSjAVQAlauW9LqDUcn+wM=\");\n_c3 = App;\nexport default App;\nvar _c, _c2, _c3;\n$RefreshReg$(_c, \"AppContainer\");\n$RefreshReg$(_c2, \"AppContent\");\n$RefreshReg$(_c3, \"App\");","map":{"version":3,"names":["React","useState","useEffect","ThemeProvider","theme","GlobalStyle","LoginForm","TodoApp","styled","jsxDEV","_jsxDEV","AppContainer","div","spacing","md","colors","primary","secondary","breakpoints","sm","_c","AppContent","_c2","App","_s","isAuthenticated","setIsAuthenticated","isLoading","setIsLoading","token","localStorage","getItem","handleLogin","setItem","handleLogout","removeItem","children","fileName","_jsxFileName","lineNumber","columnNumber","style","textAlign","color","text","onLogout","onLogin","_c3","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/App.js"],"sourcesContent":["import React, { useState, useEffect } from 'react';\r\nimport { ThemeProvider } from 'styled-components';\r\nimport { theme, GlobalStyle } from './styles/theme';\r\nimport LoginForm from './components/LoginForm';\r\nimport TodoApp from './components/TodoApp';\r\nimport styled from 'styled-components';\r\n\r\nconst AppContainer = styled.div`\r\n min-height: 100vh;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: ${({ theme }) => theme.spacing.md};\r\n background: linear-gradient(135deg, ${({ theme }) => theme.colors.primary}20, ${({ theme }) => theme.colors.secondary}20);\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n padding: ${({ theme }) => theme.spacing.sm};\r\n }\r\n`;\r\n\r\nconst AppContent = styled.div`\r\n width: 100%;\r\n max-width: 1200px;\r\n height: 100%;\r\n min-height: 600px;\r\n display: flex;\r\n flex-direction: column;\r\n position: relative;\r\n`;\r\n\r\nfunction App() {\r\n const [isAuthenticated, setIsAuthenticated] = useState(false);\r\n const [isLoading, setIsLoading] = useState(true);\r\n\r\n useEffect(() => {\r\n const token = localStorage.getItem('token');\r\n if (token) {\r\n setIsAuthenticated(true);\r\n }\r\n setIsLoading(false);\r\n }, []);\r\n\r\n const handleLogin = (token) => {\r\n localStorage.setItem('token', token);\r\n setIsAuthenticated(true);\r\n };\r\n\r\n const handleLogout = () => {\r\n localStorage.removeItem('token');\r\n setIsAuthenticated(false);\r\n };\r\n\r\n if (isLoading) {\r\n return (\r\n \r\n \r\n \r\n \r\n
\r\n 加载中...\r\n
\r\n
\r\n
\r\n
\r\n );\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {isAuthenticated ? (\r\n \r\n ) : (\r\n \r\n )}\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default App; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/539c524edeb39ecda6df0d75e795e90e68bb710e4a677ceac24b289d07b56ff4.json b/client/node_modules/.cache/babel-loader/539c524edeb39ecda6df0d75e795e90e68bb710e4a677ceac24b289d07b56ff4.json new file mode 100644 index 00000000..20ec1a83 --- /dev/null +++ b/client/node_modules/.cache/babel-loader/539c524edeb39ecda6df0d75e795e90e68bb710e4a677ceac24b289d07b56ff4.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\components\\\\TodoList.js\";\nimport React from 'react';\nimport styled, { keyframes } from 'styled-components';\nimport TodoItem from './TodoItem';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst fadeIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\nconst ListContainer = styled.div`\n background: ${({\n theme\n}) => theme.colors.glass.light};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n border-radius: ${({\n theme\n}) => theme.borderRadius.xl};\n padding: ${({\n theme\n}) => theme.spacing.xl};\n box-shadow: ${({\n theme\n}) => theme.shadows.lg};\n border: 1px solid ${({\n theme\n}) => theme.colors.glass.light};\n animation: ${fadeIn} 0.5s ease-out;\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n padding: ${({\n theme\n}) => theme.spacing.lg};\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n }\n`;\n_c = ListContainer;\nconst DateHeader = styled.div`\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: ${({\n theme\n}) => theme.spacing.xl};\n padding-bottom: ${({\n theme\n}) => theme.spacing.md};\n border-bottom: 2px solid ${({\n theme\n}) => theme.colors.glass.light};\n\n @media (prefers-color-scheme: dark) {\n border-bottom-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n margin-bottom: ${({\n theme\n}) => theme.spacing.lg};\n padding-bottom: ${({\n theme\n}) => theme.spacing.sm};\n }\n`;\n_c2 = DateHeader;\nconst DateLabel = styled.h3`\n color: ${({\n theme\n}) => theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.xl};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.semibold};\n margin: 0;\n display: flex;\n align-items: center;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n\n &::before {\n content: '📅';\n font-size: 1.2em;\n }\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n font-size: ${({\n theme\n}) => theme.typography.fontSize.lg};\n }\n`;\n_c3 = DateLabel;\nconst TodoCount = styled.div`\n display: flex;\n align-items: center;\n gap: ${({\n theme\n}) => theme.spacing.xs};\n padding: ${({\n theme\n}) => `${theme.spacing.xs} ${theme.spacing.md}`};\n background: ${({\n theme\n}) => theme.colors.primary}20;\n color: ${({\n theme\n}) => theme.colors.primary};\n border-radius: ${({\n theme\n}) => theme.borderRadius.full};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n\n &:hover {\n background: ${({\n theme\n}) => theme.colors.primary}30;\n transform: translateY(-1px);\n }\n\n &::before {\n content: '📊';\n font-size: 1.1em;\n }\n`;\n_c4 = TodoCount;\nconst TodoItems = styled.div`\n display: flex;\n flex-direction: column;\n gap: ${({\n theme\n}) => theme.spacing.md};\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n gap: ${({\n theme\n}) => theme.spacing.sm};\n }\n`;\n_c5 = TodoItems;\nconst EmptyMessage = styled.div`\n text-align: center;\n padding: ${({\n theme\n}) => theme.spacing.xl};\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.lg};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n border: 2px dashed ${({\n theme\n}) => theme.colors.glass.light};\n animation: ${fadeIn} 0.5s ease-out;\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n\n &::before {\n content: '📝';\n font-size: 2em;\n display: block;\n margin-bottom: ${({\n theme\n}) => theme.spacing.sm};\n }\n`;\n_c6 = EmptyMessage;\nfunction TodoList({\n dateLabel,\n todos,\n onToggleTodo,\n onDeleteTodo,\n onSuspendTodo,\n isHistory = false,\n isToday = false\n}) {\n const completedCount = todos.filter(todo => todo.completed).length;\n const totalCount = todos.length;\n return /*#__PURE__*/_jsxDEV(ListContainer, {\n children: [/*#__PURE__*/_jsxDEV(DateHeader, {\n children: [/*#__PURE__*/_jsxDEV(DateLabel, {\n children: dateLabel\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 137,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(TodoCount, {\n children: [completedCount, \"/\", totalCount]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 138,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 136,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(TodoItems, {\n children: todos.length === 0 ? /*#__PURE__*/_jsxDEV(EmptyMessage, {\n children: \"\\u6682\\u65E0\\u5F85\\u529E\\u4E8B\\u9879\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 145,\n columnNumber: 11\n }, this) : todos.map(todo => /*#__PURE__*/_jsxDEV(TodoItem, {\n todo: todo,\n onToggle: onToggleTodo,\n onDelete: onDeleteTodo,\n onSuspend: onSuspendTodo,\n isHistory: isHistory,\n isToday: isToday\n }, todo.id, false, {\n fileName: _jsxFileName,\n lineNumber: 150,\n columnNumber: 13\n }, this))\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 143,\n columnNumber: 7\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 135,\n columnNumber: 5\n }, this);\n}\n_c7 = TodoList;\nexport default TodoList;\nvar _c, _c2, _c3, _c4, _c5, _c6, _c7;\n$RefreshReg$(_c, \"ListContainer\");\n$RefreshReg$(_c2, \"DateHeader\");\n$RefreshReg$(_c3, \"DateLabel\");\n$RefreshReg$(_c4, \"TodoCount\");\n$RefreshReg$(_c5, \"TodoItems\");\n$RefreshReg$(_c6, \"EmptyMessage\");\n$RefreshReg$(_c7, \"TodoList\");","map":{"version":3,"names":["React","styled","keyframes","TodoItem","jsxDEV","_jsxDEV","fadeIn","ListContainer","div","theme","colors","glass","light","borderRadius","xl","spacing","shadows","lg","dark","breakpoints","md","_c","DateHeader","sm","_c2","DateLabel","h3","text","primary","typography","fontSize","fontWeight","semibold","_c3","TodoCount","xs","full","medium","transitions","default","_c4","TodoItems","_c5","EmptyMessage","secondary","_c6","TodoList","dateLabel","todos","onToggleTodo","onDeleteTodo","onSuspendTodo","isHistory","isToday","completedCount","filter","todo","completed","length","totalCount","children","fileName","_jsxFileName","lineNumber","columnNumber","map","onToggle","onDelete","onSuspend","id","_c7","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/components/TodoList.js"],"sourcesContent":["import React from 'react';\r\nimport styled, { keyframes } from 'styled-components';\r\nimport TodoItem from './TodoItem';\r\n\r\nconst fadeIn = keyframes`\r\n from {\r\n opacity: 0;\r\n transform: translateY(10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n`;\r\n\r\nconst ListContainer = styled.div`\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: ${({ theme }) => theme.borderRadius.xl};\r\n padding: ${({ theme }) => theme.spacing.xl};\r\n box-shadow: ${({ theme }) => theme.shadows.lg};\r\n border: 1px solid ${({ theme }) => theme.colors.glass.light};\r\n animation: ${fadeIn} 0.5s ease-out;\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n padding: ${({ theme }) => theme.spacing.lg};\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n }\r\n`;\r\n\r\nconst DateHeader = styled.div`\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n margin-bottom: ${({ theme }) => theme.spacing.xl};\r\n padding-bottom: ${({ theme }) => theme.spacing.md};\r\n border-bottom: 2px solid ${({ theme }) => theme.colors.glass.light};\r\n\r\n @media (prefers-color-scheme: dark) {\r\n border-bottom-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n margin-bottom: ${({ theme }) => theme.spacing.lg};\r\n padding-bottom: ${({ theme }) => theme.spacing.sm};\r\n }\r\n`;\r\n\r\nconst DateLabel = styled.h3`\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.xl};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};\r\n margin: 0;\r\n display: flex;\r\n align-items: center;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n\r\n &::before {\r\n content: '📅';\r\n font-size: 1.2em;\r\n }\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n font-size: ${({ theme }) => theme.typography.fontSize.lg};\r\n }\r\n`;\r\n\r\nconst TodoCount = styled.div`\r\n display: flex;\r\n align-items: center;\r\n gap: ${({ theme }) => theme.spacing.xs};\r\n padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.md}`};\r\n background: ${({ theme }) => theme.colors.primary}20;\r\n color: ${({ theme }) => theme.colors.primary};\r\n border-radius: ${({ theme }) => theme.borderRadius.full};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.primary}30;\r\n transform: translateY(-1px);\r\n }\r\n\r\n &::before {\r\n content: '📊';\r\n font-size: 1.1em;\r\n }\r\n`;\r\n\r\nconst TodoItems = styled.div`\r\n display: flex;\r\n flex-direction: column;\r\n gap: ${({ theme }) => theme.spacing.md};\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n }\r\n`;\r\n\r\nconst EmptyMessage = styled.div`\r\n text-align: center;\r\n padding: ${({ theme }) => theme.spacing.xl};\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.lg};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n border: 2px dashed ${({ theme }) => theme.colors.glass.light};\r\n animation: ${fadeIn} 0.5s ease-out;\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n\r\n &::before {\r\n content: '📝';\r\n font-size: 2em;\r\n display: block;\r\n margin-bottom: ${({ theme }) => theme.spacing.sm};\r\n }\r\n`;\r\n\r\nfunction TodoList({ dateLabel, todos, onToggleTodo, onDeleteTodo, onSuspendTodo, isHistory = false, isToday = false }) {\r\n const completedCount = todos.filter(todo => todo.completed).length;\r\n const totalCount = todos.length;\r\n\r\n return (\r\n \r\n \r\n {dateLabel}\r\n \r\n {completedCount}/{totalCount}\r\n \r\n \r\n \r\n \r\n {todos.length === 0 ? (\r\n \r\n 暂无待办事项\r\n \r\n ) : (\r\n todos.map(todo => (\r\n \r\n ))\r\n )}\r\n \r\n \r\n );\r\n}\r\n\r\nexport default TodoList; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/6890932def348f25727baf9b2d0a4ffea4bea464ed514dfec5f02b70780dd763.json b/client/node_modules/.cache/babel-loader/6890932def348f25727baf9b2d0a4ffea4bea464ed514dfec5f02b70780dd763.json new file mode 100644 index 00000000..532dd410 --- /dev/null +++ b/client/node_modules/.cache/babel-loader/6890932def348f25727baf9b2d0a4ffea4bea464ed514dfec5f02b70780dd763.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\components\\\\LoginForm.js\",\n _s = $RefreshSig$();\nimport React, { useState } from 'react';\nimport styled, { keyframes } from 'styled-components';\nimport { login } from '../services/api';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst fadeIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\nconst LoginContainer = styled.div`\n width: 100%;\n max-width: 400px;\n margin: 0 auto;\n padding: ${({\n theme\n}) => theme.spacing.xl};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n border-radius: ${({\n theme\n}) => theme.borderRadius.xl};\n box-shadow: ${({\n theme\n}) => theme.shadows.lg};\n animation: ${fadeIn} 0.5s ease-out;\n border: 1px solid ${({\n theme\n}) => theme.colors.glass.light};\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c = LoginContainer;\nconst LoginTitle = styled.h1`\n color: ${({\n theme\n}) => theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize['3xl']};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.bold};\n text-align: center;\n margin-bottom: ${({\n theme\n}) => theme.spacing.xl};\n display: flex;\n align-items: center;\n justify-content: center;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n\n &::before {\n content: '🔒';\n font-size: 1.2em;\n }\n`;\n_c2 = LoginTitle;\nconst Form = styled.form`\n display: flex;\n flex-direction: column;\n gap: ${({\n theme\n}) => theme.spacing.lg};\n`;\n_c3 = Form;\nconst InputGroup = styled.div`\n position: relative;\n`;\n_c4 = InputGroup;\nconst Label = styled.label`\n display: block;\n margin-bottom: ${({\n theme\n}) => theme.spacing.xs};\n color: ${({\n theme\n}) => theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n`;\n_c5 = Label;\nconst Input = styled.input`\n width: 100%;\n padding: ${({\n theme\n}) => theme.spacing.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n border: 2px solid ${({\n theme\n}) => theme.colors.glass.light};\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n color: ${({\n theme\n}) => theme.colors.text.primary};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n\n &:focus {\n outline: none;\n border-color: ${({\n theme\n}) => theme.colors.primary};\n box-shadow: 0 0 0 3px ${({\n theme\n}) => theme.colors.primary}40;\n }\n\n &::placeholder {\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n }\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c6 = Input;\nconst SubmitButton = styled.button`\n width: 100%;\n padding: ${({\n theme\n}) => theme.spacing.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.semibold};\n color: white;\n background: ${({\n theme\n}) => theme.colors.primary};\n border: none;\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n cursor: pointer;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n display: flex;\n align-items: center;\n justify-content: center;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n\n &:hover {\n background: ${({\n theme\n}) => theme.colors.primary}dd;\n transform: translateY(-1px);\n }\n\n &:active {\n transform: translateY(0);\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n }\n\n &::after {\n content: '→';\n font-size: 1.2em;\n transition: transform ${({\n theme\n}) => theme.transitions.default};\n }\n\n &:hover::after {\n transform: translateX(4px);\n }\n`;\n_c7 = SubmitButton;\nconst ErrorMessage = styled.div`\n color: ${({\n theme\n}) => theme.colors.status.error};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n text-align: center;\n margin-top: ${({\n theme\n}) => theme.spacing.sm};\n padding: ${({\n theme\n}) => theme.spacing.sm};\n background: ${({\n theme\n}) => theme.colors.status.error}20;\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n animation: ${fadeIn} 0.3s ease-out;\n`;\n_c8 = ErrorMessage;\nconst LoginHint = styled.div`\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n text-align: center;\n margin-top: ${({\n theme\n}) => theme.spacing.md};\n padding: ${({\n theme\n}) => theme.spacing.sm};\n background: ${({\n theme\n}) => theme.colors.secondary}20;\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n \n strong {\n color: ${({\n theme\n}) => theme.colors.secondary};\n }\n`;\n_c9 = LoginHint;\nfunction LoginForm({\n onLogin\n}) {\n _s();\n const [username, setUsername] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const handleSubmit = async e => {\n e.preventDefault();\n setError('');\n setIsLoading(true);\n try {\n const result = await login(username, password);\n // 保存token和用户信息\n localStorage.setItem('token', result.token);\n localStorage.setItem('user', JSON.stringify(result.user));\n onLogin(result.token, result.user);\n } catch (err) {\n var _err$response, _err$response$data;\n setError(((_err$response = err.response) === null || _err$response === void 0 ? void 0 : (_err$response$data = _err$response.data) === null || _err$response$data === void 0 ? void 0 : _err$response$data.error) || '登录失败,请重试');\n } finally {\n setIsLoading(false);\n }\n };\n return /*#__PURE__*/_jsxDEV(LoginContainer, {\n children: [/*#__PURE__*/_jsxDEV(LoginTitle, {\n children: \"\\u5DE5\\u4F5C\\u5F85\\u529E\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 189,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(Form, {\n onSubmit: handleSubmit,\n children: [/*#__PURE__*/_jsxDEV(InputGroup, {\n children: [/*#__PURE__*/_jsxDEV(Label, {\n children: \"\\u7528\\u6237\\u540D\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 192,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(Input, {\n type: \"text\",\n placeholder: \"\\u8BF7\\u8F93\\u5165\\u7528\\u6237\\u540D\",\n value: username,\n onChange: e => setUsername(e.target.value),\n disabled: isLoading,\n required: true\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 193,\n columnNumber: 11\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 191,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(InputGroup, {\n children: [/*#__PURE__*/_jsxDEV(Label, {\n children: \"\\u5BC6\\u7801\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 203,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(Input, {\n type: \"password\",\n placeholder: \"\\u8BF7\\u8F93\\u5165\\u5BC6\\u7801\",\n value: password,\n onChange: e => setPassword(e.target.value),\n disabled: isLoading,\n required: true\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 204,\n columnNumber: 11\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 202,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(SubmitButton, {\n type: \"submit\",\n disabled: isLoading,\n children: isLoading ? '登录中...' : '登录'\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 213,\n columnNumber: 9\n }, this), error && /*#__PURE__*/_jsxDEV(ErrorMessage, {\n children: error\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 216,\n columnNumber: 19\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 190,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(LoginHint, {\n children: [/*#__PURE__*/_jsxDEV(\"strong\", {\n children: \"\\u666E\\u901A\\u7528\\u6237:\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 220,\n columnNumber: 9\n }, this), \" \\u8BF7\\u4F7F\\u7528\\u7BA1\\u7406\\u5458\\u5206\\u914D\\u7684\\u8D26\\u53F7\\u5BC6\\u7801\"]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 218,\n columnNumber: 7\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 188,\n columnNumber: 5\n }, this);\n}\n_s(LoginForm, \"zVDktibOVjfWgEa3dtRS5/jU2rY=\");\n_c0 = LoginForm;\nexport default LoginForm;\nvar _c, _c2, _c3, _c4, _c5, _c6, _c7, _c8, _c9, _c0;\n$RefreshReg$(_c, \"LoginContainer\");\n$RefreshReg$(_c2, \"LoginTitle\");\n$RefreshReg$(_c3, \"Form\");\n$RefreshReg$(_c4, \"InputGroup\");\n$RefreshReg$(_c5, \"Label\");\n$RefreshReg$(_c6, \"Input\");\n$RefreshReg$(_c7, \"SubmitButton\");\n$RefreshReg$(_c8, \"ErrorMessage\");\n$RefreshReg$(_c9, \"LoginHint\");\n$RefreshReg$(_c0, \"LoginForm\");","map":{"version":3,"names":["React","useState","styled","keyframes","login","jsxDEV","_jsxDEV","fadeIn","LoginContainer","div","theme","spacing","xl","colors","glass","light","borderRadius","shadows","lg","dark","_c","LoginTitle","h1","text","primary","typography","fontSize","fontWeight","bold","sm","_c2","Form","form","_c3","InputGroup","_c4","Label","label","xs","medium","_c5","Input","input","md","base","transitions","default","secondary","_c6","SubmitButton","button","semibold","_c7","ErrorMessage","status","error","_c8","LoginHint","_c9","LoginForm","onLogin","_s","username","setUsername","password","setPassword","setError","isLoading","setIsLoading","handleSubmit","e","preventDefault","result","localStorage","setItem","token","JSON","stringify","user","err","_err$response","_err$response$data","response","data","children","fileName","_jsxFileName","lineNumber","columnNumber","onSubmit","type","placeholder","value","onChange","target","disabled","required","_c0","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/components/LoginForm.js"],"sourcesContent":["import React, { useState } from 'react';\r\nimport styled, { keyframes } from 'styled-components';\r\nimport { login } from '../services/api';\r\n\r\nconst fadeIn = keyframes`\r\n from {\r\n opacity: 0;\r\n transform: translateY(20px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n`;\r\n\r\nconst LoginContainer = styled.div`\r\n width: 100%;\r\n max-width: 400px;\r\n margin: 0 auto;\r\n padding: ${({ theme }) => theme.spacing.xl};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: ${({ theme }) => theme.borderRadius.xl};\r\n box-shadow: ${({ theme }) => theme.shadows.lg};\r\n animation: ${fadeIn} 0.5s ease-out;\r\n border: 1px solid ${({ theme }) => theme.colors.glass.light};\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst LoginTitle = styled.h1`\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize['3xl']};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.bold};\r\n text-align: center;\r\n margin-bottom: ${({ theme }) => theme.spacing.xl};\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n\r\n &::before {\r\n content: '🔒';\r\n font-size: 1.2em;\r\n }\r\n`;\r\n\r\nconst Form = styled.form`\r\n display: flex;\r\n flex-direction: column;\r\n gap: ${({ theme }) => theme.spacing.lg};\r\n`;\r\n\r\nconst InputGroup = styled.div`\r\n position: relative;\r\n`;\r\n\r\nconst Label = styled.label`\r\n display: block;\r\n margin-bottom: ${({ theme }) => theme.spacing.xs};\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n`;\r\n\r\nconst Input = styled.input`\r\n width: 100%;\r\n padding: ${({ theme }) => theme.spacing.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n border: 2px solid ${({ theme }) => theme.colors.glass.light};\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n\r\n &:focus {\r\n outline: none;\r\n border-color: ${({ theme }) => theme.colors.primary};\r\n box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40;\r\n }\r\n\r\n &::placeholder {\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst SubmitButton = styled.button`\r\n width: 100%;\r\n padding: ${({ theme }) => theme.spacing.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};\r\n color: white;\r\n background: ${({ theme }) => theme.colors.primary};\r\n border: none;\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n cursor: pointer;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.primary}dd;\r\n transform: translateY(-1px);\r\n }\r\n\r\n &:active {\r\n transform: translateY(0);\r\n }\r\n\r\n &:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n transform: none;\r\n }\r\n\r\n &::after {\r\n content: '→';\r\n font-size: 1.2em;\r\n transition: transform ${({ theme }) => theme.transitions.default};\r\n }\r\n\r\n &:hover::after {\r\n transform: translateX(4px);\r\n }\r\n`;\r\n\r\nconst ErrorMessage = styled.div`\r\n color: ${({ theme }) => theme.colors.status.error};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n text-align: center;\r\n margin-top: ${({ theme }) => theme.spacing.sm};\r\n padding: ${({ theme }) => theme.spacing.sm};\r\n background: ${({ theme }) => theme.colors.status.error}20;\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n animation: ${fadeIn} 0.3s ease-out;\r\n`;\r\n\r\nconst LoginHint = styled.div`\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n text-align: center;\r\n margin-top: ${({ theme }) => theme.spacing.md};\r\n padding: ${({ theme }) => theme.spacing.sm};\r\n background: ${({ theme }) => theme.colors.secondary}20;\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n \r\n strong {\r\n color: ${({ theme }) => theme.colors.secondary};\r\n }\r\n`;\r\n\r\nfunction LoginForm({ onLogin }) {\r\n const [username, setUsername] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [error, setError] = useState('');\r\n const [isLoading, setIsLoading] = useState(false);\r\n\r\n const handleSubmit = async (e) => {\r\n e.preventDefault();\r\n setError('');\r\n setIsLoading(true);\r\n\r\n try {\r\n const result = await login(username, password);\r\n // 保存token和用户信息\r\n localStorage.setItem('token', result.token);\r\n localStorage.setItem('user', JSON.stringify(result.user));\r\n onLogin(result.token, result.user);\r\n } catch (err) {\r\n setError(err.response?.data?.error || '登录失败,请重试');\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n \r\n 工作待办\r\n
\r\n \r\n \r\n setUsername(e.target.value)}\r\n disabled={isLoading}\r\n required\r\n />\r\n \r\n \r\n \r\n setPassword(e.target.value)}\r\n disabled={isLoading}\r\n required\r\n />\r\n \r\n \r\n {isLoading ? '登录中...' : '登录'}\r\n \r\n {error && {error}}\r\n
\r\n \r\n {/* 管理员: 用户名 admin,密码 weiMonkey2024
*/}\r\n 普通用户: 请使用管理员分配的账号密码\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default LoginForm; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/6968f7e77a72be2d50f69f6d6f57948c98340e066c0e12d0be2efe0b1469524d.json b/client/node_modules/.cache/babel-loader/6968f7e77a72be2d50f69f6d6f57948c98340e066c0e12d0be2efe0b1469524d.json new file mode 100644 index 00000000..c1f1b9b8 --- /dev/null +++ b/client/node_modules/.cache/babel-loader/6968f7e77a72be2d50f69f6d6f57948c98340e066c0e12d0be2efe0b1469524d.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\components\\\\LoginForm.js\",\n _s = $RefreshSig$();\nimport React, { useState } from 'react';\nimport styled, { keyframes } from 'styled-components';\nimport { login } from '../services/api';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst fadeIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\nconst LoginContainer = styled.div`\n width: 100%;\n max-width: 400px;\n margin: 0 auto;\n padding: ${({\n theme\n}) => theme.spacing.xl};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n border-radius: ${({\n theme\n}) => theme.borderRadius.xl};\n box-shadow: ${({\n theme\n}) => theme.shadows.lg};\n animation: ${fadeIn} 0.5s ease-out;\n border: 1px solid ${({\n theme\n}) => theme.colors.glass.light};\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c = LoginContainer;\nconst LoginTitle = styled.h1`\n color: ${({\n theme\n}) => theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize['3xl']};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.bold};\n text-align: center;\n margin-bottom: ${({\n theme\n}) => theme.spacing.xl};\n display: flex;\n align-items: center;\n justify-content: center;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n\n &::before {\n content: '🔒';\n font-size: 1.2em;\n }\n`;\n_c2 = LoginTitle;\nconst Form = styled.form`\n display: flex;\n flex-direction: column;\n gap: ${({\n theme\n}) => theme.spacing.lg};\n`;\n_c3 = Form;\nconst InputGroup = styled.div`\n position: relative;\n`;\n_c4 = InputGroup;\nconst Input = styled.input`\n width: 100%;\n padding: ${({\n theme\n}) => theme.spacing.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n border: 2px solid ${({\n theme\n}) => theme.colors.glass.light};\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n color: ${({\n theme\n}) => theme.colors.text.primary};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n\n &:focus {\n outline: none;\n border-color: ${({\n theme\n}) => theme.colors.primary};\n box-shadow: 0 0 0 3px ${({\n theme\n}) => theme.colors.primary}40;\n }\n\n &::placeholder {\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n }\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c5 = Input;\nconst SubmitButton = styled.button`\n width: 100%;\n padding: ${({\n theme\n}) => theme.spacing.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.semibold};\n color: white;\n background: ${({\n theme\n}) => theme.colors.primary};\n border: none;\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n cursor: pointer;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n display: flex;\n align-items: center;\n justify-content: center;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n\n &:hover {\n background: ${({\n theme\n}) => theme.colors.primary}dd;\n transform: translateY(-1px);\n }\n\n &:active {\n transform: translateY(0);\n }\n\n &::after {\n content: '→';\n font-size: 1.2em;\n transition: transform ${({\n theme\n}) => theme.transitions.default};\n }\n\n &:hover::after {\n transform: translateX(4px);\n }\n`;\n_c6 = SubmitButton;\nconst ErrorMessage = styled.div`\n color: ${({\n theme\n}) => theme.colors.status.error};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n text-align: center;\n margin-top: ${({\n theme\n}) => theme.spacing.sm};\n padding: ${({\n theme\n}) => theme.spacing.sm};\n background: ${({\n theme\n}) => theme.colors.status.error}20;\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n animation: ${fadeIn} 0.3s ease-out;\n`;\n_c7 = ErrorMessage;\nfunction LoginForm({\n onLogin\n}) {\n _s();\n const [password, setPassword] = useState('');\n const [error, setError] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const handleSubmit = async e => {\n e.preventDefault();\n setError('');\n setIsLoading(true);\n try {\n const {\n token\n } = await login(password);\n onLogin(token);\n } catch (err) {\n setError('密码错误,请重试');\n } finally {\n setIsLoading(false);\n }\n };\n return /*#__PURE__*/_jsxDEV(LoginContainer, {\n children: [/*#__PURE__*/_jsxDEV(LoginTitle, {\n children: \"\\u5DE5\\u4F5C\\u5F85\\u529E\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 157,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(Form, {\n onSubmit: handleSubmit,\n children: [/*#__PURE__*/_jsxDEV(InputGroup, {\n children: /*#__PURE__*/_jsxDEV(Input, {\n type: \"password\",\n placeholder: \"\\u8BF7\\u8F93\\u5165\\u8BBF\\u95EE\\u5BC6\\u7801\",\n value: password,\n onChange: e => setPassword(e.target.value),\n disabled: isLoading\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 160,\n columnNumber: 11\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 159,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(SubmitButton, {\n type: \"submit\",\n disabled: isLoading,\n children: isLoading ? '登录中...' : '登录'\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 168,\n columnNumber: 9\n }, this), error && /*#__PURE__*/_jsxDEV(ErrorMessage, {\n children: error\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 171,\n columnNumber: 19\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 158,\n columnNumber: 7\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 156,\n columnNumber: 5\n }, this);\n}\n_s(LoginForm, \"MqzPbPluSwB66fZVDC4kVqEPrOQ=\");\n_c8 = LoginForm;\nexport default LoginForm;\nvar _c, _c2, _c3, _c4, _c5, _c6, _c7, _c8;\n$RefreshReg$(_c, \"LoginContainer\");\n$RefreshReg$(_c2, \"LoginTitle\");\n$RefreshReg$(_c3, \"Form\");\n$RefreshReg$(_c4, \"InputGroup\");\n$RefreshReg$(_c5, \"Input\");\n$RefreshReg$(_c6, \"SubmitButton\");\n$RefreshReg$(_c7, \"ErrorMessage\");\n$RefreshReg$(_c8, \"LoginForm\");","map":{"version":3,"names":["React","useState","styled","keyframes","login","jsxDEV","_jsxDEV","fadeIn","LoginContainer","div","theme","spacing","xl","colors","glass","light","borderRadius","shadows","lg","dark","_c","LoginTitle","h1","text","primary","typography","fontSize","fontWeight","bold","sm","_c2","Form","form","_c3","InputGroup","_c4","Input","input","md","base","transitions","default","secondary","_c5","SubmitButton","button","semibold","_c6","ErrorMessage","status","error","_c7","LoginForm","onLogin","_s","password","setPassword","setError","isLoading","setIsLoading","handleSubmit","e","preventDefault","token","err","children","fileName","_jsxFileName","lineNumber","columnNumber","onSubmit","type","placeholder","value","onChange","target","disabled","_c8","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/components/LoginForm.js"],"sourcesContent":["import React, { useState } from 'react';\r\nimport styled, { keyframes } from 'styled-components';\r\nimport { login } from '../services/api';\r\n\r\nconst fadeIn = keyframes`\r\n from {\r\n opacity: 0;\r\n transform: translateY(20px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n`;\r\n\r\nconst LoginContainer = styled.div`\r\n width: 100%;\r\n max-width: 400px;\r\n margin: 0 auto;\r\n padding: ${({ theme }) => theme.spacing.xl};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: ${({ theme }) => theme.borderRadius.xl};\r\n box-shadow: ${({ theme }) => theme.shadows.lg};\r\n animation: ${fadeIn} 0.5s ease-out;\r\n border: 1px solid ${({ theme }) => theme.colors.glass.light};\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst LoginTitle = styled.h1`\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize['3xl']};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.bold};\r\n text-align: center;\r\n margin-bottom: ${({ theme }) => theme.spacing.xl};\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n\r\n &::before {\r\n content: '🔒';\r\n font-size: 1.2em;\r\n }\r\n`;\r\n\r\nconst Form = styled.form`\r\n display: flex;\r\n flex-direction: column;\r\n gap: ${({ theme }) => theme.spacing.lg};\r\n`;\r\n\r\nconst InputGroup = styled.div`\r\n position: relative;\r\n`;\r\n\r\nconst Input = styled.input`\r\n width: 100%;\r\n padding: ${({ theme }) => theme.spacing.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n border: 2px solid ${({ theme }) => theme.colors.glass.light};\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n\r\n &:focus {\r\n outline: none;\r\n border-color: ${({ theme }) => theme.colors.primary};\r\n box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40;\r\n }\r\n\r\n &::placeholder {\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst SubmitButton = styled.button`\r\n width: 100%;\r\n padding: ${({ theme }) => theme.spacing.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};\r\n color: white;\r\n background: ${({ theme }) => theme.colors.primary};\r\n border: none;\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n cursor: pointer;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.primary}dd;\r\n transform: translateY(-1px);\r\n }\r\n\r\n &:active {\r\n transform: translateY(0);\r\n }\r\n\r\n &::after {\r\n content: '→';\r\n font-size: 1.2em;\r\n transition: transform ${({ theme }) => theme.transitions.default};\r\n }\r\n\r\n &:hover::after {\r\n transform: translateX(4px);\r\n }\r\n`;\r\n\r\nconst ErrorMessage = styled.div`\r\n color: ${({ theme }) => theme.colors.status.error};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n text-align: center;\r\n margin-top: ${({ theme }) => theme.spacing.sm};\r\n padding: ${({ theme }) => theme.spacing.sm};\r\n background: ${({ theme }) => theme.colors.status.error}20;\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n animation: ${fadeIn} 0.3s ease-out;\r\n`;\r\n\r\nfunction LoginForm({ onLogin }) {\r\n const [password, setPassword] = useState('');\r\n const [error, setError] = useState('');\r\n const [isLoading, setIsLoading] = useState(false);\r\n\r\n const handleSubmit = async (e) => {\r\n e.preventDefault();\r\n setError('');\r\n setIsLoading(true);\r\n\r\n try {\r\n const { token } = await login(password);\r\n onLogin(token);\r\n } catch (err) {\r\n setError('密码错误,请重试');\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n \r\n 工作待办\r\n
\r\n \r\n setPassword(e.target.value)}\r\n disabled={isLoading}\r\n />\r\n \r\n \r\n {isLoading ? '登录中...' : '登录'}\r\n \r\n {error && {error}}\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default LoginForm; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/78f620a59586d8198533a07930695eeb28c536cbaca0eae3dacabca298afa0d8.json b/client/node_modules/.cache/babel-loader/78f620a59586d8198533a07930695eeb28c536cbaca0eae3dacabca298afa0d8.json new file mode 100644 index 00000000..2417710c --- /dev/null +++ b/client/node_modules/.cache/babel-loader/78f620a59586d8198533a07930695eeb28c536cbaca0eae3dacabca298afa0d8.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\components\\\\TodoItem.js\",\n _s = $RefreshSig$();\nimport React, { useState } from 'react';\nimport styled, { keyframes } from 'styled-components';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst slideIn = keyframes`\n from {\n opacity: 0;\n transform: translateX(-10px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n`;\nconst fadeIn = keyframes`\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n`;\nconst scaleIn = keyframes`\n from {\n transform: scale(0.95);\n }\n to {\n transform: scale(1);\n }\n`;\nconst ItemContainer = styled.div`\n background: ${({\n theme\n}) => theme.colors.glass.light};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n padding: ${({\n theme\n}) => theme.spacing.lg};\n display: flex;\n align-items: center;\n gap: ${({\n theme\n}) => theme.spacing.md};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n border: 1px solid ${({\n theme\n}) => theme.colors.glass.light};\n animation: ${slideIn} 0.3s ease-out;\n position: relative;\n overflow: hidden;\n cursor: pointer;\n\n &:hover {\n transform: translateY(-2px);\n box-shadow: ${({\n theme\n}) => theme.shadows.md};\n }\n\n &:active {\n transform: translateY(0);\n box-shadow: ${({\n theme\n}) => theme.shadows.sm};\n }\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n padding: ${({\n theme\n}) => theme.spacing.md};\n }\n`;\n_c = ItemContainer;\nconst Checkbox = styled.input`\n appearance: none;\n width: 24px;\n height: 24px;\n border: 2px solid ${({\n theme\n}) => theme.colors.primary};\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n cursor: pointer;\n position: relative;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n flex-shrink: 0;\n\n &:checked {\n background: ${({\n theme\n}) => theme.colors.primary};\n border-color: ${({\n theme\n}) => theme.colors.primary};\n }\n\n &:checked::after {\n content: '✓';\n position: absolute;\n color: white;\n font-size: 16px;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n animation: ${fadeIn} 0.2s ease-out;\n }\n\n &:hover {\n transform: scale(1.1);\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 3px ${({\n theme\n}) => theme.colors.primary}40;\n }\n`;\n_c2 = Checkbox;\nconst Content = styled.div`\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: ${({\n theme\n}) => theme.spacing.xs};\n min-width: 0; // 防止内容溢出\n`;\n_c3 = Content;\nconst Title = styled.span`\n color: ${({\n theme,\n completed\n}) => completed ? theme.colors.text.secondary : theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n text-decoration: ${({\n completed\n}) => completed ? 'line-through' : 'none'};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n_c4 = Title;\nconst Description = styled.p`\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n margin: 0;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n line-height: 1.4;\n`;\n_c5 = Description;\nconst PriorityBadge = styled.span`\n padding: ${({\n theme\n}) => `${theme.spacing.xs} ${theme.spacing.sm}`};\n border-radius: ${({\n theme\n}) => theme.borderRadius.full};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.xs};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n background: ${({\n theme,\n priority\n}) => theme.colors.priority[priority]}20;\n color: ${({\n theme,\n priority\n}) => theme.colors.priority[priority]};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n display: inline-flex;\n align-items: center;\n gap: ${({\n theme\n}) => theme.spacing.xs};\n\n &::before {\n content: ${({\n priority\n}) => {\n switch (priority) {\n case 'urgent':\n return '\"🚨\"';\n case 'high':\n return '\"🔥\"';\n case 'medium':\n return '\"⚡\"';\n case 'low':\n return '\"🐢\"';\n default:\n return '\"📌\"';\n }\n}};\n font-size: 1.1em;\n }\n\n &:hover {\n transform: translateY(-1px);\n background: ${({\n theme,\n priority\n}) => theme.colors.priority[priority]}30;\n }\n`;\n_c6 = PriorityBadge;\nconst ButtonGroup = styled.div`\n display: flex;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n opacity: 0;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n position: absolute;\n right: ${({\n theme\n}) => theme.spacing.lg};\n top: 50%;\n transform: translateY(-50%);\n\n ${ItemContainer}:hover & {\n opacity: 1;\n }\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n opacity: 1;\n position: static;\n transform: none;\n }\n`;\n_c7 = ButtonGroup;\nconst ActionButton = styled.button`\n background: none;\n border: none;\n padding: ${({\n theme\n}) => theme.spacing.sm};\n cursor: pointer;\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.2em;\n\n &:hover {\n background: ${({\n theme\n}) => theme.colors.glass.light};\n color: ${({\n theme\n}) => theme.colors.primary};\n transform: translateY(-1px);\n }\n\n &:active {\n transform: translateY(0);\n }\n\n &:focus {\n outline: none;\n box-shadow: 0 0 0 3px ${({\n theme\n}) => theme.colors.primary}40;\n }\n\n @media (prefers-color-scheme: dark) {\n &:hover {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n }\n`;\n_c8 = ActionButton;\nconst StatusBadge = styled.span`\n position: absolute;\n top: ${({\n theme\n}) => theme.spacing.sm};\n right: ${({\n theme\n}) => theme.spacing.sm};\n padding: ${({\n theme\n}) => `${theme.spacing.xs} ${theme.spacing.sm}`};\n border-radius: ${({\n theme\n}) => theme.borderRadius.full};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.xs};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n background: ${({\n theme,\n status\n}) => theme.colors.status[status]}20;\n color: ${({\n theme,\n status\n}) => theme.colors.status[status]};\n animation: ${fadeIn} 0.3s ease-out;\n display: flex;\n align-items: center;\n gap: ${({\n theme\n}) => theme.spacing.xs};\n\n &::before {\n content: ${({\n status\n}) => {\n switch (status) {\n case 'warning':\n return '\"⏸️\"';\n case 'success':\n return '\"✅\"';\n case 'error':\n return '\"❌\"';\n default:\n return '\"📌\"';\n }\n}};\n font-size: 1.1em;\n }\n`;\n_c9 = StatusBadge;\nconst Tooltip = styled.div`\n position: absolute;\n bottom: 100%;\n left: 50%;\n transform: translateX(-50%);\n padding: ${({\n theme\n}) => `${theme.spacing.xs} ${theme.spacing.sm}`};\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n color: ${({\n theme\n}) => theme.colors.text.light};\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.xs};\n white-space: nowrap;\n opacity: 0;\n visibility: hidden;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n pointer-events: none;\n z-index: 1000;\n\n ${ActionButton}:hover & {\n opacity: 1;\n visibility: visible;\n transform: translateX(-50%) translateY(-4px);\n }\n`;\n_c0 = Tooltip;\nfunction TodoItem({\n todo,\n onToggle,\n onDelete,\n onSuspend,\n isHistory,\n isToday\n}) {\n _s();\n const [isHovered, setIsHovered] = useState(false);\n const getPriorityLabel = priority => {\n const labels = {\n low: '低优先级',\n medium: '中优先级',\n high: '高优先级',\n urgent: '紧急'\n };\n return labels[priority] || priority;\n };\n const handleToggle = e => {\n e.stopPropagation();\n onToggle(todo.id, !todo.completed);\n };\n const handleDelete = e => {\n e.stopPropagation();\n onDelete(todo.id);\n };\n const handleSuspend = e => {\n e.stopPropagation();\n onSuspend(todo.id);\n };\n return /*#__PURE__*/_jsxDEV(ItemContainer, {\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: () => setIsHovered(false),\n onClick: handleToggle,\n children: [/*#__PURE__*/_jsxDEV(Checkbox, {\n type: \"checkbox\",\n checked: todo.completed,\n onChange: handleToggle\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 309,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(Content, {\n children: [/*#__PURE__*/_jsxDEV(Title, {\n completed: todo.completed,\n children: todo.title\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 315,\n columnNumber: 9\n }, this), todo.description && /*#__PURE__*/_jsxDEV(Description, {\n children: todo.description\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 319,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(PriorityBadge, {\n priority: todo.priority,\n children: getPriorityLabel(todo.priority)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 321,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 314,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(ButtonGroup, {\n children: [isToday && !todo.completed && !todo.suspended && /*#__PURE__*/_jsxDEV(ActionButton, {\n onClick: handleSuspend,\n title: \"\\u6302\\u8D77\",\n children: [\"\\u23F8\\uFE0F\", /*#__PURE__*/_jsxDEV(Tooltip, {\n children: \"\\u6302\\u8D77\\u4EFB\\u52A1\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 329,\n columnNumber: 13\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 327,\n columnNumber: 11\n }, this), !isHistory && /*#__PURE__*/_jsxDEV(ActionButton, {\n onClick: handleDelete,\n title: \"\\u5220\\u9664\",\n children: [\"\\uD83D\\uDDD1\\uFE0F\", /*#__PURE__*/_jsxDEV(Tooltip, {\n children: \"\\u5220\\u9664\\u4EFB\\u52A1\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 335,\n columnNumber: 13\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 333,\n columnNumber: 11\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 325,\n columnNumber: 7\n }, this), todo.suspended && /*#__PURE__*/_jsxDEV(StatusBadge, {\n status: \"warning\",\n children: \"\\u5DF2\\u6302\\u8D77\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 340,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 304,\n columnNumber: 5\n }, this);\n}\n_s(TodoItem, \"FPQn8a98tPjpohC7NUYORQR8GJE=\");\n_c1 = TodoItem;\nexport default TodoItem;\nvar _c, _c2, _c3, _c4, _c5, _c6, _c7, _c8, _c9, _c0, _c1;\n$RefreshReg$(_c, \"ItemContainer\");\n$RefreshReg$(_c2, \"Checkbox\");\n$RefreshReg$(_c3, \"Content\");\n$RefreshReg$(_c4, \"Title\");\n$RefreshReg$(_c5, \"Description\");\n$RefreshReg$(_c6, \"PriorityBadge\");\n$RefreshReg$(_c7, \"ButtonGroup\");\n$RefreshReg$(_c8, \"ActionButton\");\n$RefreshReg$(_c9, \"StatusBadge\");\n$RefreshReg$(_c0, \"Tooltip\");\n$RefreshReg$(_c1, \"TodoItem\");","map":{"version":3,"names":["React","useState","styled","keyframes","jsxDEV","_jsxDEV","slideIn","fadeIn","scaleIn","ItemContainer","div","theme","colors","glass","light","borderRadius","lg","spacing","md","transitions","default","shadows","sm","dark","breakpoints","_c","Checkbox","input","primary","_c2","Content","xs","_c3","Title","span","completed","text","secondary","typography","fontSize","base","fontWeight","medium","_c4","Description","p","_c5","PriorityBadge","full","priority","_c6","ButtonGroup","_c7","ActionButton","button","_c8","StatusBadge","status","_c9","Tooltip","_c0","TodoItem","todo","onToggle","onDelete","onSuspend","isHistory","isToday","_s","isHovered","setIsHovered","getPriorityLabel","labels","low","high","urgent","handleToggle","e","stopPropagation","id","handleDelete","handleSuspend","onMouseEnter","onMouseLeave","onClick","children","type","checked","onChange","fileName","_jsxFileName","lineNumber","columnNumber","title","description","suspended","_c1","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/components/TodoItem.js"],"sourcesContent":["import React, { useState } from 'react';\r\nimport styled, { keyframes } from 'styled-components';\r\n\r\nconst slideIn = keyframes`\r\n from {\r\n opacity: 0;\r\n transform: translateX(-10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0);\r\n }\r\n`;\r\n\r\nconst fadeIn = keyframes`\r\n from {\r\n opacity: 0;\r\n }\r\n to {\r\n opacity: 1;\r\n }\r\n`;\r\n\r\nconst scaleIn = keyframes`\r\n from {\r\n transform: scale(0.95);\r\n }\r\n to {\r\n transform: scale(1);\r\n }\r\n`;\r\n\r\nconst ItemContainer = styled.div`\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n padding: ${({ theme }) => theme.spacing.lg};\r\n display: flex;\r\n align-items: center;\r\n gap: ${({ theme }) => theme.spacing.md};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n border: 1px solid ${({ theme }) => theme.colors.glass.light};\r\n animation: ${slideIn} 0.3s ease-out;\r\n position: relative;\r\n overflow: hidden;\r\n cursor: pointer;\r\n\r\n &:hover {\r\n transform: translateY(-2px);\r\n box-shadow: ${({ theme }) => theme.shadows.md};\r\n }\r\n\r\n &:active {\r\n transform: translateY(0);\r\n box-shadow: ${({ theme }) => theme.shadows.sm};\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n padding: ${({ theme }) => theme.spacing.md};\r\n }\r\n`;\r\n\r\nconst Checkbox = styled.input`\r\n appearance: none;\r\n width: 24px;\r\n height: 24px;\r\n border: 2px solid ${({ theme }) => theme.colors.primary};\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n cursor: pointer;\r\n position: relative;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n flex-shrink: 0;\r\n\r\n &:checked {\r\n background: ${({ theme }) => theme.colors.primary};\r\n border-color: ${({ theme }) => theme.colors.primary};\r\n }\r\n\r\n &:checked::after {\r\n content: '✓';\r\n position: absolute;\r\n color: white;\r\n font-size: 16px;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n animation: ${fadeIn} 0.2s ease-out;\r\n }\r\n\r\n &:hover {\r\n transform: scale(1.1);\r\n }\r\n\r\n &:focus {\r\n outline: none;\r\n box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40;\r\n }\r\n`;\r\n\r\nconst Content = styled.div`\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: ${({ theme }) => theme.spacing.xs};\r\n min-width: 0; // 防止内容溢出\r\n`;\r\n\r\nconst Title = styled.span`\r\n color: ${({ theme, completed }) => completed ? theme.colors.text.secondary : theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n text-decoration: ${({ completed }) => completed ? 'line-through' : 'none'};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n`;\r\n\r\nconst Description = styled.p`\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n line-height: 1.4;\r\n`;\r\n\r\nconst PriorityBadge = styled.span`\r\n padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.sm}`};\r\n border-radius: ${({ theme }) => theme.borderRadius.full};\r\n font-size: ${({ theme }) => theme.typography.fontSize.xs};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n background: ${({ theme, priority }) => theme.colors.priority[priority]}20;\r\n color: ${({ theme, priority }) => theme.colors.priority[priority]};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n display: inline-flex;\r\n align-items: center;\r\n gap: ${({ theme }) => theme.spacing.xs};\r\n\r\n &::before {\r\n content: ${({ priority }) => {\r\n switch (priority) {\r\n case 'urgent': return '\"🚨\"';\r\n case 'high': return '\"🔥\"';\r\n case 'medium': return '\"⚡\"';\r\n case 'low': return '\"🐢\"';\r\n default: return '\"📌\"';\r\n }\r\n }};\r\n font-size: 1.1em;\r\n }\r\n\r\n &:hover {\r\n transform: translateY(-1px);\r\n background: ${({ theme, priority }) => theme.colors.priority[priority]}30;\r\n }\r\n`;\r\n\r\nconst ButtonGroup = styled.div`\r\n display: flex;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n opacity: 0;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n position: absolute;\r\n right: ${({ theme }) => theme.spacing.lg};\r\n top: 50%;\r\n transform: translateY(-50%);\r\n\r\n ${ItemContainer}:hover & {\r\n opacity: 1;\r\n }\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n opacity: 1;\r\n position: static;\r\n transform: none;\r\n }\r\n`;\r\n\r\nconst ActionButton = styled.button`\r\n background: none;\r\n border: none;\r\n padding: ${({ theme }) => theme.spacing.sm};\r\n cursor: pointer;\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 1.2em;\r\n\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n color: ${({ theme }) => theme.colors.primary};\r\n transform: translateY(-1px);\r\n }\r\n\r\n &:active {\r\n transform: translateY(0);\r\n }\r\n\r\n &:focus {\r\n outline: none;\r\n box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40;\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n }\r\n`;\r\n\r\nconst StatusBadge = styled.span`\r\n position: absolute;\r\n top: ${({ theme }) => theme.spacing.sm};\r\n right: ${({ theme }) => theme.spacing.sm};\r\n padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.sm}`};\r\n border-radius: ${({ theme }) => theme.borderRadius.full};\r\n font-size: ${({ theme }) => theme.typography.fontSize.xs};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n background: ${({ theme, status }) => theme.colors.status[status]}20;\r\n color: ${({ theme, status }) => theme.colors.status[status]};\r\n animation: ${fadeIn} 0.3s ease-out;\r\n display: flex;\r\n align-items: center;\r\n gap: ${({ theme }) => theme.spacing.xs};\r\n\r\n &::before {\r\n content: ${({ status }) => {\r\n switch (status) {\r\n case 'warning': return '\"⏸️\"';\r\n case 'success': return '\"✅\"';\r\n case 'error': return '\"❌\"';\r\n default: return '\"📌\"';\r\n }\r\n }};\r\n font-size: 1.1em;\r\n }\r\n`;\r\n\r\nconst Tooltip = styled.div`\r\n position: absolute;\r\n bottom: 100%;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.sm}`};\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n color: ${({ theme }) => theme.colors.text.light};\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.xs};\r\n white-space: nowrap;\r\n opacity: 0;\r\n visibility: hidden;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n pointer-events: none;\r\n z-index: 1000;\r\n\r\n ${ActionButton}:hover & {\r\n opacity: 1;\r\n visibility: visible;\r\n transform: translateX(-50%) translateY(-4px);\r\n }\r\n`;\r\n\r\nfunction TodoItem({ todo, onToggle, onDelete, onSuspend, isHistory, isToday }) {\r\n const [isHovered, setIsHovered] = useState(false);\r\n\r\n const getPriorityLabel = (priority) => {\r\n const labels = {\r\n low: '低优先级',\r\n medium: '中优先级',\r\n high: '高优先级',\r\n urgent: '紧急'\r\n };\r\n return labels[priority] || priority;\r\n };\r\n\r\n const handleToggle = (e) => {\r\n e.stopPropagation();\r\n onToggle(todo.id, !todo.completed);\r\n };\r\n\r\n const handleDelete = (e) => {\r\n e.stopPropagation();\r\n onDelete(todo.id);\r\n };\r\n\r\n const handleSuspend = (e) => {\r\n e.stopPropagation();\r\n onSuspend(todo.id);\r\n };\r\n\r\n return (\r\n setIsHovered(true)}\r\n onMouseLeave={() => setIsHovered(false)}\r\n onClick={handleToggle}\r\n >\r\n \r\n \r\n \r\n {todo.title}\r\n \r\n {todo.description && (\r\n {todo.description}\r\n )}\r\n \r\n {getPriorityLabel(todo.priority)}\r\n \r\n \r\n \r\n {isToday && !todo.completed && !todo.suspended && (\r\n \r\n ⏸️\r\n 挂起任务\r\n \r\n )}\r\n {!isHistory && (\r\n \r\n 🗑️\r\n 删除任务\r\n \r\n )}\r\n \r\n {todo.suspended && (\r\n 已挂起\r\n )}\r\n \r\n );\r\n}\r\n\r\nexport default TodoItem; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/99232906c17a6e16207b89bca5511463db9bcf01dd90abbeff4c7966080e76ff.json b/client/node_modules/.cache/babel-loader/99232906c17a6e16207b89bca5511463db9bcf01dd90abbeff4c7966080e76ff.json new file mode 100644 index 00000000..fc0f19bb --- /dev/null +++ b/client/node_modules/.cache/babel-loader/99232906c17a6e16207b89bca5511463db9bcf01dd90abbeff4c7966080e76ff.json @@ -0,0 +1 @@ +{"ast":null,"code":"import axios from 'axios';\nconst API_URL = 'http://localhost:5000/api';\n\n// 创建axios实例\nconst api = axios.create({\n baseURL: API_URL\n});\n\n// 请求拦截器,自动添加token\napi.interceptors.request.use(config => {\n const token = localStorage.getItem('token');\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n});\n\n// 用户登录\nexport const login = async (username, password) => {\n const response = await api.post('/auth/login', {\n username,\n password\n });\n return response.data;\n};\n\n// 管理员注册新用户\nexport const registerUser = async (username, password) => {\n const response = await api.post('/auth/register', {\n username,\n password\n });\n return response.data;\n};\n\n// 获取所有用户(仅管理员)\nexport const getUsers = async () => {\n const response = await api.get('/users');\n return response.data;\n};\n\n// 获取待办事项\nexport const getTodos = async () => {\n const response = await api.get('/todos');\n return response.data;\n};\n\n// 获取历史待办事项\nexport const getHistoryTodos = async () => {\n const response = await api.get('/todos/history');\n return response.data;\n};\n\n// 获取挂起的待办事项\nexport const getSuspendedTodos = async () => {\n const response = await api.get('/todos/suspended');\n return response.data;\n};\n\n// 迁移历史未完成待办到今天\nexport const migratePendingTodos = async () => {\n const response = await api.post('/todos/migrate-pending');\n return response.data;\n};\n\n// 挂起待办事项\nexport const suspendTodo = async id => {\n const response = await api.put(`/todos/${id}/suspend`);\n return response.data;\n};\n\n// 恢复挂起的待办事项\nexport const resumeTodo = async id => {\n const response = await api.put(`/todos/${id}/resume`);\n return response.data;\n};\n\n// 创建待办事项\nexport const createTodo = async todoData => {\n const response = await api.post('/todos', todoData);\n return response.data;\n};\n\n// 更新待办事项\nexport const updateTodo = async (id, updateData) => {\n const response = await api.put(`/todos/${id}`, updateData);\n return response.data;\n};\n\n// 删除待办事项\nexport const deleteTodo = async id => {\n const response = await api.delete(`/todos/${id}`);\n return response.data;\n};","map":{"version":3,"names":["axios","API_URL","api","create","baseURL","interceptors","request","use","config","token","localStorage","getItem","headers","Authorization","login","username","password","response","post","data","registerUser","getUsers","get","getTodos","getHistoryTodos","getSuspendedTodos","migratePendingTodos","suspendTodo","id","put","resumeTodo","createTodo","todoData","updateTodo","updateData","deleteTodo","delete"],"sources":["D:/aiproject/goAgent/todo/client/src/services/api.js"],"sourcesContent":["import axios from 'axios';\r\n\r\nconst API_URL = 'http://localhost:5000/api';\r\n\r\n// 创建axios实例\r\nconst api = axios.create({\r\n baseURL: API_URL,\r\n});\r\n\r\n// 请求拦截器,自动添加token\r\napi.interceptors.request.use((config) => {\r\n const token = localStorage.getItem('token');\r\n if (token) {\r\n config.headers.Authorization = `Bearer ${token}`;\r\n }\r\n return config;\r\n});\r\n\r\n// 用户登录\r\nexport const login = async (username, password) => {\r\n const response = await api.post('/auth/login', { username, password });\r\n return response.data;\r\n};\r\n\r\n// 管理员注册新用户\r\nexport const registerUser = async (username, password) => {\r\n const response = await api.post('/auth/register', { username, password });\r\n return response.data;\r\n};\r\n\r\n// 获取所有用户(仅管理员)\r\nexport const getUsers = async () => {\r\n const response = await api.get('/users');\r\n return response.data;\r\n};\r\n\r\n// 获取待办事项\r\nexport const getTodos = async () => {\r\n const response = await api.get('/todos');\r\n return response.data;\r\n};\r\n\r\n// 获取历史待办事项\r\nexport const getHistoryTodos = async () => {\r\n const response = await api.get('/todos/history');\r\n return response.data;\r\n};\r\n\r\n// 获取挂起的待办事项\r\nexport const getSuspendedTodos = async () => {\r\n const response = await api.get('/todos/suspended');\r\n return response.data;\r\n};\r\n\r\n// 迁移历史未完成待办到今天\r\nexport const migratePendingTodos = async () => {\r\n const response = await api.post('/todos/migrate-pending');\r\n return response.data;\r\n};\r\n\r\n// 挂起待办事项\r\nexport const suspendTodo = async (id) => {\r\n const response = await api.put(`/todos/${id}/suspend`);\r\n return response.data;\r\n};\r\n\r\n// 恢复挂起的待办事项\r\nexport const resumeTodo = async (id) => {\r\n const response = await api.put(`/todos/${id}/resume`);\r\n return response.data;\r\n};\r\n\r\n// 创建待办事项\r\nexport const createTodo = async (todoData) => {\r\n const response = await api.post('/todos', todoData);\r\n return response.data;\r\n};\r\n\r\n// 更新待办事项\r\nexport const updateTodo = async (id, updateData) => {\r\n const response = await api.put(`/todos/${id}`, updateData);\r\n return response.data;\r\n};\r\n\r\n// 删除待办事项\r\nexport const deleteTodo = async (id) => {\r\n const response = await api.delete(`/todos/${id}`);\r\n return response.data;\r\n}; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/a3f616c9017e66dcf51c2603c701552917a6c080312cac72dffbf5afa616af2e.json b/client/node_modules/.cache/babel-loader/a3f616c9017e66dcf51c2603c701552917a6c080312cac72dffbf5afa616af2e.json new file mode 100644 index 00000000..deac92fd --- /dev/null +++ b/client/node_modules/.cache/babel-loader/a3f616c9017e66dcf51c2603c701552917a6c080312cac72dffbf5afa616af2e.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\App.js\",\n _s = $RefreshSig$();\nimport React, { useState, useEffect } from 'react';\nimport { ThemeProvider } from 'styled-components';\nimport { theme, GlobalStyle } from './styles/theme';\nimport LoginForm from './components/LoginForm';\nimport TodoApp from './components/TodoApp';\nimport styled from 'styled-components';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst AppContainer = styled.div`\n min-height: 100vh;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: ${({\n theme\n}) => theme.spacing.md};\n background: linear-gradient(135deg, ${({\n theme\n}) => theme.colors.primary}20, ${({\n theme\n}) => theme.colors.secondary}20);\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n\n @media (max-width: ${({\n theme\n}) => theme.breakpoints.md}) {\n padding: ${({\n theme\n}) => theme.spacing.sm};\n }\n`;\n_c = AppContainer;\nconst AppContent = styled.div`\n width: 100%;\n max-width: 1200px;\n height: 100%;\n min-height: 600px;\n display: flex;\n flex-direction: column;\n position: relative;\n`;\n_c2 = AppContent;\nfunction App() {\n _s();\n const [isAuthenticated, setIsAuthenticated] = useState(false);\n const [currentUser, setCurrentUser] = useState(null);\n const [isLoading, setIsLoading] = useState(true);\n useEffect(() => {\n const token = localStorage.getItem('token');\n const user = localStorage.getItem('user');\n if (token && user) {\n try {\n const parsedUser = JSON.parse(user);\n setCurrentUser(parsedUser);\n setIsAuthenticated(true);\n } catch (error) {\n console.error('解析用户信息失败:', error);\n localStorage.removeItem('token');\n localStorage.removeItem('user');\n }\n }\n setIsLoading(false);\n }, []);\n const handleLogin = (token, user) => {\n localStorage.setItem('token', token);\n localStorage.setItem('user', JSON.stringify(user));\n setCurrentUser(user);\n setIsAuthenticated(true);\n };\n const handleLogout = () => {\n localStorage.removeItem('token');\n localStorage.removeItem('user');\n setCurrentUser(null);\n setIsAuthenticated(false);\n };\n if (isLoading) {\n return /*#__PURE__*/_jsxDEV(ThemeProvider, {\n theme: theme,\n children: [/*#__PURE__*/_jsxDEV(GlobalStyle, {}, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 73,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(AppContainer, {\n children: /*#__PURE__*/_jsxDEV(AppContent, {\n children: /*#__PURE__*/_jsxDEV(\"div\", {\n style: {\n textAlign: 'center',\n color: theme.colors.text.secondary,\n fontSize: theme.typography.fontSize.lg\n },\n children: \"\\u52A0\\u8F7D\\u4E2D...\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 76,\n columnNumber: 13\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 75,\n columnNumber: 11\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 74,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 72,\n columnNumber: 7\n }, this);\n }\n return /*#__PURE__*/_jsxDEV(ThemeProvider, {\n theme: theme,\n children: [/*#__PURE__*/_jsxDEV(GlobalStyle, {}, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 91,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(AppContainer, {\n children: /*#__PURE__*/_jsxDEV(AppContent, {\n children: isAuthenticated ? /*#__PURE__*/_jsxDEV(TodoApp, {\n onLogout: handleLogout,\n currentUser: currentUser\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 95,\n columnNumber: 13\n }, this) : /*#__PURE__*/_jsxDEV(LoginForm, {\n onLogin: handleLogin\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 100,\n columnNumber: 13\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 93,\n columnNumber: 9\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 92,\n columnNumber: 7\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 90,\n columnNumber: 5\n }, this);\n}\n_s(App, \"FXF743FTDIL7d5dzD4kgct754PE=\");\n_c3 = App;\nexport default App;\nvar _c, _c2, _c3;\n$RefreshReg$(_c, \"AppContainer\");\n$RefreshReg$(_c2, \"AppContent\");\n$RefreshReg$(_c3, \"App\");","map":{"version":3,"names":["React","useState","useEffect","ThemeProvider","theme","GlobalStyle","LoginForm","TodoApp","styled","jsxDEV","_jsxDEV","AppContainer","div","spacing","md","colors","primary","secondary","breakpoints","sm","_c","AppContent","_c2","App","_s","isAuthenticated","setIsAuthenticated","currentUser","setCurrentUser","isLoading","setIsLoading","token","localStorage","getItem","user","parsedUser","JSON","parse","error","console","removeItem","handleLogin","setItem","stringify","handleLogout","children","fileName","_jsxFileName","lineNumber","columnNumber","style","textAlign","color","text","fontSize","typography","lg","onLogout","onLogin","_c3","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/App.js"],"sourcesContent":["import React, { useState, useEffect } from 'react';\r\nimport { ThemeProvider } from 'styled-components';\r\nimport { theme, GlobalStyle } from './styles/theme';\r\nimport LoginForm from './components/LoginForm';\r\nimport TodoApp from './components/TodoApp';\r\nimport styled from 'styled-components';\r\n\r\nconst AppContainer = styled.div`\r\n min-height: 100vh;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: ${({ theme }) => theme.spacing.md};\r\n background: linear-gradient(135deg, ${({ theme }) => theme.colors.primary}20, ${({ theme }) => theme.colors.secondary}20);\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n\r\n @media (max-width: ${({ theme }) => theme.breakpoints.md}) {\r\n padding: ${({ theme }) => theme.spacing.sm};\r\n }\r\n`;\r\n\r\nconst AppContent = styled.div`\r\n width: 100%;\r\n max-width: 1200px;\r\n height: 100%;\r\n min-height: 600px;\r\n display: flex;\r\n flex-direction: column;\r\n position: relative;\r\n`;\r\n\r\nfunction App() {\r\n const [isAuthenticated, setIsAuthenticated] = useState(false);\r\n const [currentUser, setCurrentUser] = useState(null);\r\n const [isLoading, setIsLoading] = useState(true);\r\n\r\n useEffect(() => {\r\n const token = localStorage.getItem('token');\r\n const user = localStorage.getItem('user');\r\n \r\n if (token && user) {\r\n try {\r\n const parsedUser = JSON.parse(user);\r\n setCurrentUser(parsedUser);\r\n setIsAuthenticated(true);\r\n } catch (error) {\r\n console.error('解析用户信息失败:', error);\r\n localStorage.removeItem('token');\r\n localStorage.removeItem('user');\r\n }\r\n }\r\n setIsLoading(false);\r\n }, []);\r\n\r\n const handleLogin = (token, user) => {\r\n localStorage.setItem('token', token);\r\n localStorage.setItem('user', JSON.stringify(user));\r\n setCurrentUser(user);\r\n setIsAuthenticated(true);\r\n };\r\n\r\n const handleLogout = () => {\r\n localStorage.removeItem('token');\r\n localStorage.removeItem('user');\r\n setCurrentUser(null);\r\n setIsAuthenticated(false);\r\n };\r\n\r\n if (isLoading) {\r\n return (\r\n \r\n \r\n \r\n \r\n
\r\n 加载中...\r\n
\r\n
\r\n
\r\n
\r\n );\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {isAuthenticated ? (\r\n \r\n ) : (\r\n \r\n )}\r\n \r\n \r\n \r\n );\r\n}\r\n\r\nexport default App; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/a616666ea4a177469b0fd76aedb319694a281e5ee46980909379cee874007e72.json b/client/node_modules/.cache/babel-loader/a616666ea4a177469b0fd76aedb319694a281e5ee46980909379cee874007e72.json new file mode 100644 index 00000000..bbe2be18 --- /dev/null +++ b/client/node_modules/.cache/babel-loader/a616666ea4a177469b0fd76aedb319694a281e5ee46980909379cee874007e72.json @@ -0,0 +1 @@ +{"ast":null,"code":"import { createGlobalStyle } from 'styled-components';\nexport const theme = {\n colors: {\n primary: '#6C5CE7',\n // 主色:柔和紫\n secondary: '#00B894',\n // 辅助色:生态绿\n background: {\n light: 'rgba(255, 255, 255, 0.95)',\n dark: 'rgba(30, 30, 30, 0.95)'\n },\n text: {\n primary: '#2D3436',\n secondary: '#636E72',\n light: '#FFFFFF'\n },\n priority: {\n low: '#95A5A6',\n medium: '#3498DB',\n high: '#E67E22',\n urgent: '#E74C3C'\n },\n status: {\n success: '#00B894',\n warning: '#FDCB6E',\n error: '#E74C3C'\n },\n glass: {\n light: 'rgba(255, 255, 255, 0.7)',\n dark: 'rgba(30, 30, 30, 0.7)'\n }\n },\n typography: {\n fontFamily: {\n pc: 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n mobile: 'SF Pro Rounded, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif'\n },\n fontSize: {\n xs: '0.75rem',\n sm: '0.875rem',\n base: '1rem',\n lg: '1.125rem',\n xl: '1.25rem',\n '2xl': '1.5rem',\n '3xl': '1.875rem',\n '4xl': '2.25rem'\n },\n fontWeight: {\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700\n }\n },\n spacing: {\n xs: '0.25rem',\n sm: '0.5rem',\n md: '1rem',\n lg: '1.5rem',\n xl: '2rem',\n '2xl': '3rem'\n },\n borderRadius: {\n sm: '0.375rem',\n md: '0.5rem',\n lg: '0.75rem',\n xl: '1rem',\n full: '9999px'\n },\n shadows: {\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',\n xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1)'\n },\n transitions: {\n default: '0.3s ease',\n fast: '0.15s ease',\n slow: '0.5s ease'\n },\n breakpoints: {\n sm: '640px',\n md: '768px',\n lg: '1024px',\n xl: '1280px',\n '2xl': '1536px'\n }\n};\nexport const GlobalStyle = createGlobalStyle`\n :root {\n --primary: ${theme.colors.primary};\n --secondary: ${theme.colors.secondary};\n --background: ${theme.colors.background.light};\n --text-primary: ${theme.colors.text.primary};\n --text-secondary: ${theme.colors.text.secondary};\n }\n\n @media (prefers-color-scheme: dark) {\n :root {\n --background: ${theme.colors.background.dark};\n --text-primary: ${theme.colors.text.light};\n --text-secondary: ${theme.colors.text.light};\n }\n }\n\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n\n body {\n font-family: ${theme.typography.fontFamily.pc};\n background: var(--background);\n color: var(--text-primary);\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n\n @media (max-width: ${theme.breakpoints.md}) {\n body {\n font-family: ${theme.typography.fontFamily.mobile};\n }\n }\n\n button {\n font-family: inherit;\n }\n\n /* 滚动条样式 */\n ::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n }\n\n ::-webkit-scrollbar-track {\n background: transparent;\n }\n\n ::-webkit-scrollbar-thumb {\n background: ${theme.colors.primary}40;\n border-radius: ${theme.borderRadius.full};\n }\n\n ::-webkit-scrollbar-thumb:hover {\n background: ${theme.colors.primary}60;\n }\n`;","map":{"version":3,"names":["createGlobalStyle","theme","colors","primary","secondary","background","light","dark","text","priority","low","medium","high","urgent","status","success","warning","error","glass","typography","fontFamily","pc","mobile","fontSize","xs","sm","base","lg","xl","fontWeight","normal","semibold","bold","spacing","md","borderRadius","full","shadows","transitions","default","fast","slow","breakpoints","GlobalStyle"],"sources":["D:/aiproject/goAgent/todo/client/src/styles/theme.js"],"sourcesContent":["import { createGlobalStyle } from 'styled-components';\r\n\r\nexport const theme = {\r\n colors: {\r\n primary: '#6C5CE7', // 主色:柔和紫\r\n secondary: '#00B894', // 辅助色:生态绿\r\n background: {\r\n light: 'rgba(255, 255, 255, 0.95)',\r\n dark: 'rgba(30, 30, 30, 0.95)',\r\n },\r\n text: {\r\n primary: '#2D3436',\r\n secondary: '#636E72',\r\n light: '#FFFFFF',\r\n },\r\n priority: {\r\n low: '#95A5A6',\r\n medium: '#3498DB',\r\n high: '#E67E22',\r\n urgent: '#E74C3C',\r\n },\r\n status: {\r\n success: '#00B894',\r\n warning: '#FDCB6E',\r\n error: '#E74C3C',\r\n },\r\n glass: {\r\n light: 'rgba(255, 255, 255, 0.7)',\r\n dark: 'rgba(30, 30, 30, 0.7)',\r\n }\r\n },\r\n typography: {\r\n fontFamily: {\r\n pc: 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n mobile: 'SF Pro Rounded, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n },\r\n fontSize: {\r\n xs: '0.75rem',\r\n sm: '0.875rem',\r\n base: '1rem',\r\n lg: '1.125rem',\r\n xl: '1.25rem',\r\n '2xl': '1.5rem',\r\n '3xl': '1.875rem',\r\n '4xl': '2.25rem',\r\n },\r\n fontWeight: {\r\n normal: 400,\r\n medium: 500,\r\n semibold: 600,\r\n bold: 700,\r\n },\r\n },\r\n spacing: {\r\n xs: '0.25rem',\r\n sm: '0.5rem',\r\n md: '1rem',\r\n lg: '1.5rem',\r\n xl: '2rem',\r\n '2xl': '3rem',\r\n },\r\n borderRadius: {\r\n sm: '0.375rem',\r\n md: '0.5rem',\r\n lg: '0.75rem',\r\n xl: '1rem',\r\n full: '9999px',\r\n },\r\n shadows: {\r\n sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',\r\n md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',\r\n lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',\r\n xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1)',\r\n },\r\n transitions: {\r\n default: '0.3s ease',\r\n fast: '0.15s ease',\r\n slow: '0.5s ease',\r\n },\r\n breakpoints: {\r\n sm: '640px',\r\n md: '768px',\r\n lg: '1024px',\r\n xl: '1280px',\r\n '2xl': '1536px',\r\n },\r\n};\r\n\r\nexport const GlobalStyle = createGlobalStyle`\r\n :root {\r\n --primary: ${theme.colors.primary};\r\n --secondary: ${theme.colors.secondary};\r\n --background: ${theme.colors.background.light};\r\n --text-primary: ${theme.colors.text.primary};\r\n --text-secondary: ${theme.colors.text.secondary};\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n :root {\r\n --background: ${theme.colors.background.dark};\r\n --text-primary: ${theme.colors.text.light};\r\n --text-secondary: ${theme.colors.text.light};\r\n }\r\n }\r\n\r\n * {\r\n margin: 0;\r\n padding: 0;\r\n box-sizing: border-box;\r\n }\r\n\r\n body {\r\n font-family: ${theme.typography.fontFamily.pc};\r\n background: var(--background);\r\n color: var(--text-primary);\r\n line-height: 1.5;\r\n -webkit-font-smoothing: antialiased;\r\n -moz-osx-font-smoothing: grayscale;\r\n }\r\n\r\n @media (max-width: ${theme.breakpoints.md}) {\r\n body {\r\n font-family: ${theme.typography.fontFamily.mobile};\r\n }\r\n }\r\n\r\n button {\r\n font-family: inherit;\r\n }\r\n\r\n /* 滚动条样式 */\r\n ::-webkit-scrollbar {\r\n width: 8px;\r\n height: 8px;\r\n }\r\n\r\n ::-webkit-scrollbar-track {\r\n background: transparent;\r\n }\r\n\r\n ::-webkit-scrollbar-thumb {\r\n background: ${theme.colors.primary}40;\r\n border-radius: ${theme.borderRadius.full};\r\n }\r\n\r\n ::-webkit-scrollbar-thumb:hover {\r\n background: ${theme.colors.primary}60;\r\n }\r\n`; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/b3f0c93f3dc4a017964e62dd7dabc688b11ae4f7d6df8f0271444e698ee040b6.json b/client/node_modules/.cache/babel-loader/b3f0c93f3dc4a017964e62dd7dabc688b11ae4f7d6df8f0271444e698ee040b6.json new file mode 100644 index 00000000..100a43db --- /dev/null +++ b/client/node_modules/.cache/babel-loader/b3f0c93f3dc4a017964e62dd7dabc688b11ae4f7d6df8f0271444e698ee040b6.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\components\\\\TodoApp.js\",\n _s = $RefreshSig$();\nimport React, { useState, useEffect } from 'react';\nimport styled from 'styled-components';\nimport { format, parseISO, isToday, isYesterday, isTomorrow } from 'date-fns';\nimport { getTodos, createTodo, updateTodo, deleteTodo, migratePendingTodos, suspendTodo } from '../services/api';\nimport TodoForm from './TodoForm';\nimport TodoList from './TodoList';\nimport HistoryTodos from './HistoryTodos';\nimport SuspendedTodos from './SuspendedTodos';\nimport UserManagement from './UserManagement';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst AppContainer = styled.div`\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n border-radius: 20px;\n padding: 40px;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);\n width: 100%;\n max-width: 1200px;\n max-height: 95vh;\n overflow-y: auto;\n min-height: 600px;\n`;\n_c = AppContainer;\nconst Header = styled.div`\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 40px;\n padding-bottom: 25px;\n border-bottom: 2px solid #f0f0f0;\n`;\n_c2 = Header;\nconst TitleSection = styled.div`\n display: flex;\n flex-direction: column;\n gap: 8px;\n`;\n_c3 = TitleSection;\nconst Title = styled.h1`\n color: #333;\n font-size: 32px;\n font-weight: 300;\n margin: 0;\n`;\n_c4 = Title;\nconst UserInfo = styled.div`\n color: #666;\n font-size: 14px;\n display: flex;\n align-items: center;\n gap: 8px;\n\n .username {\n font-weight: 500;\n color: #667eea;\n }\n\n .role {\n padding: 2px 8px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 500;\n }\n\n .admin {\n background: rgba(255, 152, 0, 0.1);\n color: #ff9800;\n }\n\n .user {\n background: rgba(102, 126, 234, 0.1);\n color: #667eea;\n }\n`;\n_c5 = UserInfo;\nconst HeaderActions = styled.div`\n display: flex;\n gap: 12px;\n align-items: center;\n flex-wrap: wrap;\n\n @media (max-width: 768px) {\n flex-direction: column;\n align-items: stretch;\n gap: 8px;\n }\n`;\n_c6 = HeaderActions;\nconst ActionButton = styled.button`\n background: ${({\n variant,\n theme\n}) => {\n var _theme$colors;\n switch (variant) {\n case 'primary':\n return (theme === null || theme === void 0 ? void 0 : (_theme$colors = theme.colors) === null || _theme$colors === void 0 ? void 0 : _theme$colors.primary) || '#667eea';\n case 'warning':\n return '#ff9800';\n case 'success':\n return '#00B894';\n case 'danger':\n return '#e74c3c';\n default:\n return 'transparent';\n }\n}};\n color: ${({\n variant\n}) => variant === 'default' ? '#666' : 'white'};\n border: ${({\n variant\n}) => variant === 'default' ? '2px solid #e1e5e9' : 'none'};\n padding: 10px 20px;\n border-radius: 8px;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.3s ease;\n display: flex;\n align-items: center;\n gap: 8px;\n white-space: nowrap;\n\n &:hover {\n transform: translateY(-1px);\n ${({\n variant\n}) => {\n if (variant === 'default') {\n return `\n border-color: #667eea;\n color: #667eea;\n `;\n }\n return 'opacity: 0.9;';\n}}\n }\n\n &::before {\n content: ${({\n icon\n}) => icon ? `'${icon}'` : 'none'};\n font-size: 16px;\n }\n`;\n_c7 = ActionButton;\nconst Content = styled.div`\n display: flex;\n flex-direction: column;\n gap: 35px;\n`;\n_c8 = Content;\nconst LoadingMessage = styled.div`\n text-align: center;\n color: #666;\n font-size: 18px;\n padding: 60px;\n`;\n_c9 = LoadingMessage;\nconst EmptyMessage = styled.div`\n text-align: center;\n color: #999;\n font-size: 18px;\n padding: 60px;\n background: rgba(102, 126, 234, 0.05);\n border-radius: 16px;\n border: 2px dashed #e1e5e9;\n`;\n_c0 = EmptyMessage;\nfunction TodoApp({\n onLogout,\n currentUser\n}) {\n _s();\n const [todos, setTodos] = useState([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState('');\n const [showHistory, setShowHistory] = useState(false);\n const [showSuspended, setShowSuspended] = useState(false);\n const [showUserManagement, setShowUserManagement] = useState(false);\n const [successMessage, setSuccessMessage] = useState('');\n useEffect(() => {\n loadTodos();\n }, []);\n const loadTodos = async () => {\n try {\n setLoading(true);\n const data = await getTodos();\n setTodos(data);\n } catch (err) {\n setError('加载待办事项失败');\n console.error('Load todos error:', err);\n } finally {\n setLoading(false);\n }\n };\n const handleAddTodo = async todoData => {\n try {\n const newTodo = await createTodo(todoData);\n setTodos(prev => [newTodo, ...prev]);\n } catch (err) {\n setError('添加待办事项失败');\n console.error('Add todo error:', err);\n }\n };\n const handleToggleTodo = async (id, completed) => {\n try {\n const updatedTodo = await updateTodo(id, {\n completed\n });\n setTodos(prev => prev.map(todo => todo.id === id ? {\n ...todo,\n completed\n } : todo));\n } catch (err) {\n setError('更新待办事项失败');\n console.error('Toggle todo error:', err);\n }\n };\n const handleDeleteTodo = async id => {\n try {\n await deleteTodo(id);\n setTodos(prev => prev.filter(todo => todo.id !== id));\n setSuccessMessage('待办事项已删除');\n setTimeout(() => setSuccessMessage(''), 3000);\n } catch (err) {\n setError('删除待办事项失败');\n console.error('Delete todo error:', err);\n }\n };\n const handleSuspendTodo = async id => {\n try {\n await suspendTodo(id);\n setTodos(prev => prev.filter(todo => todo.id !== id));\n setSuccessMessage('待办事项已挂起');\n setTimeout(() => setSuccessMessage(''), 3000);\n } catch (err) {\n setError('挂起待办事项失败');\n console.error('Suspend todo error:', err);\n }\n };\n const handleMigratePendingTodos = async () => {\n try {\n const result = await migratePendingTodos();\n if (result.migratedCount > 0) {\n setSuccessMessage(result.message);\n // 重新加载待办事项以显示迁移的内容\n await loadTodos();\n } else {\n setSuccessMessage('没有找到需要迁移的未完成待办事项');\n }\n setTimeout(() => setSuccessMessage(''), 5000);\n } catch (err) {\n setError('迁移待办事项失败');\n console.error('Migrate pending todos error:', err);\n }\n };\n\n // 按日期分组待办事项\n const groupTodosByDate = todos => {\n const groups = {};\n todos.forEach(todo => {\n const date = todo.date;\n if (!groups[date]) {\n groups[date] = [];\n }\n groups[date].push(todo);\n });\n\n // 按日期排序\n const sortedDates = Object.keys(groups).sort((a, b) => new Date(b) - new Date(a));\n return sortedDates.map(date => ({\n date,\n todos: groups[date].sort((a, b) => {\n // 按优先级排序\n const priorityOrder = {\n urgent: 4,\n high: 3,\n medium: 2,\n low: 1\n };\n return priorityOrder[b.priority] - priorityOrder[a.priority];\n })\n }));\n };\n const formatDateLabel = dateString => {\n const date = parseISO(dateString);\n if (isToday(date)) {\n return '今天';\n } else if (isYesterday(date)) {\n return '昨天';\n } else if (isTomorrow(date)) {\n return '明天';\n } else {\n // 简化日期格式,不使用中文语言包\n const month = date.getMonth() + 1;\n const day = date.getDate();\n const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];\n const weekday = weekdays[date.getDay()];\n return `${month}月${day}日 ${weekday}`;\n }\n };\n const groupedTodos = groupTodosByDate(todos);\n\n // 如果正在显示用户管理视图\n if (showUserManagement) {\n return /*#__PURE__*/_jsxDEV(AppContainer, {\n children: /*#__PURE__*/_jsxDEV(UserManagement, {\n onBack: () => setShowUserManagement(false)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 294,\n columnNumber: 9\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 293,\n columnNumber: 7\n }, this);\n }\n\n // 如果正在显示历史视图\n if (showHistory) {\n return /*#__PURE__*/_jsxDEV(AppContainer, {\n children: /*#__PURE__*/_jsxDEV(HistoryTodos, {\n onBack: () => setShowHistory(false)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 303,\n columnNumber: 9\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 302,\n columnNumber: 7\n }, this);\n }\n\n // 如果正在显示挂起视图\n if (showSuspended) {\n return /*#__PURE__*/_jsxDEV(AppContainer, {\n children: /*#__PURE__*/_jsxDEV(SuspendedTodos, {\n onBack: () => setShowSuspended(false)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 312,\n columnNumber: 9\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 311,\n columnNumber: 7\n }, this);\n }\n if (loading) {\n return /*#__PURE__*/_jsxDEV(AppContainer, {\n children: /*#__PURE__*/_jsxDEV(LoadingMessage, {\n children: \"\\u52A0\\u8F7D\\u4E2D...\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 320,\n columnNumber: 9\n }, this)\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 319,\n columnNumber: 7\n }, this);\n }\n return /*#__PURE__*/_jsxDEV(AppContainer, {\n children: [/*#__PURE__*/_jsxDEV(Header, {\n children: [/*#__PURE__*/_jsxDEV(TitleSection, {\n children: [/*#__PURE__*/_jsxDEV(Title, {\n children: \"\\u5DE5\\u4F5C\\u5F85\\u529E\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 329,\n columnNumber: 11\n }, this), currentUser && /*#__PURE__*/_jsxDEV(UserInfo, {\n children: [\"\\u6B22\\u8FCE\\uFF0C\", /*#__PURE__*/_jsxDEV(\"span\", {\n className: \"username\",\n children: currentUser.username\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 332,\n columnNumber: 18\n }, this), /*#__PURE__*/_jsxDEV(\"span\", {\n className: `role ${currentUser.is_admin ? 'admin' : 'user'}`,\n children: currentUser.is_admin ? '管理员' : '用户'\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 333,\n columnNumber: 15\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 331,\n columnNumber: 13\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 328,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(HeaderActions, {\n children: [/*#__PURE__*/_jsxDEV(ActionButton, {\n variant: \"warning\",\n icon: \"\\uD83D\\uDCE6\",\n onClick: handleMigratePendingTodos,\n children: \"\\u8FC1\\u79FB\\u672A\\u5B8C\\u6210\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 340,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(ActionButton, {\n variant: \"success\",\n icon: \"\\u23F8\\uFE0F\",\n onClick: () => setShowSuspended(true),\n children: \"\\u6302\\u8D77\\u5F85\\u529E\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 347,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(ActionButton, {\n variant: \"primary\",\n icon: \"\\uD83D\\uDCDA\",\n onClick: () => setShowHistory(true),\n children: \"\\u5386\\u53F2\\u8BB0\\u5F55\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 354,\n columnNumber: 11\n }, this), (currentUser === null || currentUser === void 0 ? void 0 : currentUser.is_admin) && /*#__PURE__*/_jsxDEV(ActionButton, {\n variant: \"primary\",\n icon: \"\\uD83D\\uDC65\",\n onClick: () => setShowUserManagement(true),\n children: \"\\u7528\\u6237\\u7BA1\\u7406\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 362,\n columnNumber: 13\n }, this), /*#__PURE__*/_jsxDEV(ActionButton, {\n variant: \"default\",\n onClick: onLogout,\n children: \"\\u9000\\u51FA\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 370,\n columnNumber: 11\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 339,\n columnNumber: 9\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 327,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(Content, {\n children: [/*#__PURE__*/_jsxDEV(TodoForm, {\n onAddTodo: handleAddTodo\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 380,\n columnNumber: 9\n }, this), error && /*#__PURE__*/_jsxDEV(\"div\", {\n style: {\n color: '#e74c3c',\n textAlign: 'center',\n padding: '15px',\n fontSize: '16px'\n },\n children: error\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 383,\n columnNumber: 11\n }, this), successMessage && /*#__PURE__*/_jsxDEV(\"div\", {\n style: {\n color: '#27ae60',\n textAlign: 'center',\n padding: '15px',\n fontSize: '16px',\n background: 'rgba(39, 174, 96, 0.1)',\n borderRadius: '8px',\n marginBottom: '20px'\n },\n children: successMessage\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 389,\n columnNumber: 11\n }, this), groupedTodos.length === 0 ? /*#__PURE__*/_jsxDEV(EmptyMessage, {\n children: \"\\uD83D\\uDCDD \\u8FD8\\u6CA1\\u6709\\u5F85\\u529E\\u4E8B\\u9879\\uFF0C\\u70B9\\u51FB\\u4E0A\\u65B9\\u6DFB\\u52A0\\u7B2C\\u4E00\\u4E2A\\u5427\\uFF01\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 403,\n columnNumber: 11\n }, this) : groupedTodos.map(({\n date,\n todos\n }) => {\n const dateObj = parseISO(date);\n const isTodayList = isToday(dateObj);\n return /*#__PURE__*/_jsxDEV(TodoList, {\n dateLabel: formatDateLabel(date),\n todos: todos,\n onToggleTodo: handleToggleTodo,\n onDeleteTodo: handleDeleteTodo,\n onSuspendTodo: handleSuspendTodo,\n isToday: isTodayList\n }, date, false, {\n fileName: _jsxFileName,\n lineNumber: 412,\n columnNumber: 15\n }, this);\n })]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 379,\n columnNumber: 7\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 326,\n columnNumber: 5\n }, this);\n}\n_s(TodoApp, \"63l4QgJ1S2zOr+A5Qp1BKbVZ1MM=\");\n_c1 = TodoApp;\nexport default TodoApp;\nvar _c, _c2, _c3, _c4, _c5, _c6, _c7, _c8, _c9, _c0, _c1;\n$RefreshReg$(_c, \"AppContainer\");\n$RefreshReg$(_c2, \"Header\");\n$RefreshReg$(_c3, \"TitleSection\");\n$RefreshReg$(_c4, \"Title\");\n$RefreshReg$(_c5, \"UserInfo\");\n$RefreshReg$(_c6, \"HeaderActions\");\n$RefreshReg$(_c7, \"ActionButton\");\n$RefreshReg$(_c8, \"Content\");\n$RefreshReg$(_c9, \"LoadingMessage\");\n$RefreshReg$(_c0, \"EmptyMessage\");\n$RefreshReg$(_c1, \"TodoApp\");","map":{"version":3,"names":["React","useState","useEffect","styled","format","parseISO","isToday","isYesterday","isTomorrow","getTodos","createTodo","updateTodo","deleteTodo","migratePendingTodos","suspendTodo","TodoForm","TodoList","HistoryTodos","SuspendedTodos","UserManagement","jsxDEV","_jsxDEV","AppContainer","div","_c","Header","_c2","TitleSection","_c3","Title","h1","_c4","UserInfo","_c5","HeaderActions","_c6","ActionButton","button","variant","theme","_theme$colors","colors","primary","icon","_c7","Content","_c8","LoadingMessage","_c9","EmptyMessage","_c0","TodoApp","onLogout","currentUser","_s","todos","setTodos","loading","setLoading","error","setError","showHistory","setShowHistory","showSuspended","setShowSuspended","showUserManagement","setShowUserManagement","successMessage","setSuccessMessage","loadTodos","data","err","console","handleAddTodo","todoData","newTodo","prev","handleToggleTodo","id","completed","updatedTodo","map","todo","handleDeleteTodo","filter","setTimeout","handleSuspendTodo","handleMigratePendingTodos","result","migratedCount","message","groupTodosByDate","groups","forEach","date","push","sortedDates","Object","keys","sort","a","b","Date","priorityOrder","urgent","high","medium","low","priority","formatDateLabel","dateString","month","getMonth","day","getDate","weekdays","weekday","getDay","groupedTodos","children","onBack","fileName","_jsxFileName","lineNumber","columnNumber","className","username","is_admin","onClick","onAddTodo","style","color","textAlign","padding","fontSize","background","borderRadius","marginBottom","length","dateObj","isTodayList","dateLabel","onToggleTodo","onDeleteTodo","onSuspendTodo","_c1","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/components/TodoApp.js"],"sourcesContent":["import React, { useState, useEffect } from 'react';\r\nimport styled from 'styled-components';\r\nimport { format, parseISO, isToday, isYesterday, isTomorrow } from 'date-fns';\r\nimport { getTodos, createTodo, updateTodo, deleteTodo, migratePendingTodos, suspendTodo } from '../services/api';\r\nimport TodoForm from './TodoForm';\r\nimport TodoList from './TodoList';\r\nimport HistoryTodos from './HistoryTodos';\r\nimport SuspendedTodos from './SuspendedTodos';\r\nimport UserManagement from './UserManagement';\r\n\r\nconst AppContainer = styled.div`\r\n background: rgba(255, 255, 255, 0.95);\r\n backdrop-filter: blur(10px);\r\n border-radius: 20px;\r\n padding: 40px;\r\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);\r\n width: 100%;\r\n max-width: 1200px;\r\n max-height: 95vh;\r\n overflow-y: auto;\r\n min-height: 600px;\r\n`;\r\n\r\nconst Header = styled.div`\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 40px;\r\n padding-bottom: 25px;\r\n border-bottom: 2px solid #f0f0f0;\r\n`;\r\n\r\nconst TitleSection = styled.div`\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n`;\r\n\r\nconst Title = styled.h1`\r\n color: #333;\r\n font-size: 32px;\r\n font-weight: 300;\r\n margin: 0;\r\n`;\r\n\r\nconst UserInfo = styled.div`\r\n color: #666;\r\n font-size: 14px;\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n\r\n .username {\r\n font-weight: 500;\r\n color: #667eea;\r\n }\r\n\r\n .role {\r\n padding: 2px 8px;\r\n border-radius: 12px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n }\r\n\r\n .admin {\r\n background: rgba(255, 152, 0, 0.1);\r\n color: #ff9800;\r\n }\r\n\r\n .user {\r\n background: rgba(102, 126, 234, 0.1);\r\n color: #667eea;\r\n }\r\n`;\r\n\r\nconst HeaderActions = styled.div`\r\n display: flex;\r\n gap: 12px;\r\n align-items: center;\r\n flex-wrap: wrap;\r\n\r\n @media (max-width: 768px) {\r\n flex-direction: column;\r\n align-items: stretch;\r\n gap: 8px;\r\n }\r\n`;\r\n\r\nconst ActionButton = styled.button`\r\n background: ${({ variant, theme }) => {\r\n switch (variant) {\r\n case 'primary': return theme?.colors?.primary || '#667eea';\r\n case 'warning': return '#ff9800';\r\n case 'success': return '#00B894';\r\n case 'danger': return '#e74c3c';\r\n default: return 'transparent';\r\n }\r\n }};\r\n color: ${({ variant }) => variant === 'default' ? '#666' : 'white'};\r\n border: ${({ variant }) => variant === 'default' ? '2px solid #e1e5e9' : 'none'};\r\n padding: 10px 20px;\r\n border-radius: 8px;\r\n font-size: 14px;\r\n cursor: pointer;\r\n transition: all 0.3s ease;\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n white-space: nowrap;\r\n\r\n &:hover {\r\n transform: translateY(-1px);\r\n ${({ variant }) => {\r\n if (variant === 'default') {\r\n return `\r\n border-color: #667eea;\r\n color: #667eea;\r\n `;\r\n }\r\n return 'opacity: 0.9;';\r\n }}\r\n }\r\n\r\n &::before {\r\n content: ${({ icon }) => icon ? `'${icon}'` : 'none'};\r\n font-size: 16px;\r\n }\r\n`;\r\n\r\nconst Content = styled.div`\r\n display: flex;\r\n flex-direction: column;\r\n gap: 35px;\r\n`;\r\n\r\nconst LoadingMessage = styled.div`\r\n text-align: center;\r\n color: #666;\r\n font-size: 18px;\r\n padding: 60px;\r\n`;\r\n\r\nconst EmptyMessage = styled.div`\r\n text-align: center;\r\n color: #999;\r\n font-size: 18px;\r\n padding: 60px;\r\n background: rgba(102, 126, 234, 0.05);\r\n border-radius: 16px;\r\n border: 2px dashed #e1e5e9;\r\n`;\r\n\r\nfunction TodoApp({ onLogout, currentUser }) {\r\n const [todos, setTodos] = useState([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState('');\r\n const [showHistory, setShowHistory] = useState(false);\r\n const [showSuspended, setShowSuspended] = useState(false);\r\n const [showUserManagement, setShowUserManagement] = useState(false);\r\n const [successMessage, setSuccessMessage] = useState('');\r\n\r\n useEffect(() => {\r\n loadTodos();\r\n }, []);\r\n\r\n const loadTodos = async () => {\r\n try {\r\n setLoading(true);\r\n const data = await getTodos();\r\n setTodos(data);\r\n } catch (err) {\r\n setError('加载待办事项失败');\r\n console.error('Load todos error:', err);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n const handleAddTodo = async (todoData) => {\r\n try {\r\n const newTodo = await createTodo(todoData);\r\n setTodos(prev => [newTodo, ...prev]);\r\n } catch (err) {\r\n setError('添加待办事项失败');\r\n console.error('Add todo error:', err);\r\n }\r\n };\r\n\r\n const handleToggleTodo = async (id, completed) => {\r\n try {\r\n const updatedTodo = await updateTodo(id, { completed });\r\n setTodos(prev => \r\n prev.map(todo => \r\n todo.id === id ? { ...todo, completed } : todo\r\n )\r\n );\r\n } catch (err) {\r\n setError('更新待办事项失败');\r\n console.error('Toggle todo error:', err);\r\n }\r\n };\r\n\r\n const handleDeleteTodo = async (id) => {\r\n try {\r\n await deleteTodo(id);\r\n setTodos(prev => prev.filter(todo => todo.id !== id));\r\n setSuccessMessage('待办事项已删除');\r\n setTimeout(() => setSuccessMessage(''), 3000);\r\n } catch (err) {\r\n setError('删除待办事项失败');\r\n console.error('Delete todo error:', err);\r\n }\r\n };\r\n\r\n const handleSuspendTodo = async (id) => {\r\n try {\r\n await suspendTodo(id);\r\n setTodos(prev => prev.filter(todo => todo.id !== id));\r\n setSuccessMessage('待办事项已挂起');\r\n setTimeout(() => setSuccessMessage(''), 3000);\r\n } catch (err) {\r\n setError('挂起待办事项失败');\r\n console.error('Suspend todo error:', err);\r\n }\r\n };\r\n\r\n const handleMigratePendingTodos = async () => {\r\n try {\r\n const result = await migratePendingTodos();\r\n if (result.migratedCount > 0) {\r\n setSuccessMessage(result.message);\r\n // 重新加载待办事项以显示迁移的内容\r\n await loadTodos();\r\n } else {\r\n setSuccessMessage('没有找到需要迁移的未完成待办事项');\r\n }\r\n setTimeout(() => setSuccessMessage(''), 5000);\r\n } catch (err) {\r\n setError('迁移待办事项失败');\r\n console.error('Migrate pending todos error:', err);\r\n }\r\n };\r\n\r\n // 按日期分组待办事项\r\n const groupTodosByDate = (todos) => {\r\n const groups = {};\r\n \r\n todos.forEach(todo => {\r\n const date = todo.date;\r\n if (!groups[date]) {\r\n groups[date] = [];\r\n }\r\n groups[date].push(todo);\r\n });\r\n\r\n // 按日期排序\r\n const sortedDates = Object.keys(groups).sort((a, b) => new Date(b) - new Date(a));\r\n \r\n return sortedDates.map(date => ({\r\n date,\r\n todos: groups[date].sort((a, b) => {\r\n // 按优先级排序\r\n const priorityOrder = { urgent: 4, high: 3, medium: 2, low: 1 };\r\n return priorityOrder[b.priority] - priorityOrder[a.priority];\r\n })\r\n }));\r\n };\r\n\r\n const formatDateLabel = (dateString) => {\r\n const date = parseISO(dateString);\r\n \r\n if (isToday(date)) {\r\n return '今天';\r\n } else if (isYesterday(date)) {\r\n return '昨天';\r\n } else if (isTomorrow(date)) {\r\n return '明天';\r\n } else {\r\n // 简化日期格式,不使用中文语言包\r\n const month = date.getMonth() + 1;\r\n const day = date.getDate();\r\n const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];\r\n const weekday = weekdays[date.getDay()];\r\n return `${month}月${day}日 ${weekday}`;\r\n }\r\n };\r\n\r\n const groupedTodos = groupTodosByDate(todos);\r\n\r\n // 如果正在显示用户管理视图\r\n if (showUserManagement) {\r\n return (\r\n \r\n setShowUserManagement(false)} />\r\n \r\n );\r\n }\r\n\r\n // 如果正在显示历史视图\r\n if (showHistory) {\r\n return (\r\n \r\n setShowHistory(false)} />\r\n \r\n );\r\n }\r\n\r\n // 如果正在显示挂起视图\r\n if (showSuspended) {\r\n return (\r\n \r\n setShowSuspended(false)} />\r\n \r\n );\r\n }\r\n\r\n if (loading) {\r\n return (\r\n \r\n 加载中...\r\n \r\n );\r\n }\r\n\r\n return (\r\n \r\n
\r\n \r\n 工作待办\r\n {currentUser && (\r\n \r\n 欢迎,{currentUser.username}\r\n \r\n {currentUser.is_admin ? '管理员' : '用户'}\r\n \r\n \r\n )}\r\n \r\n \r\n \r\n 迁移未完成\r\n \r\n setShowSuspended(true)}\r\n >\r\n 挂起待办\r\n \r\n setShowHistory(true)}\r\n >\r\n 历史记录\r\n \r\n {currentUser?.is_admin && (\r\n setShowUserManagement(true)}\r\n >\r\n 用户管理\r\n \r\n )}\r\n \r\n 退出\r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n {error && (\r\n
\r\n {error}\r\n
\r\n )}\r\n \r\n {successMessage && (\r\n
\r\n {successMessage}\r\n
\r\n )}\r\n \r\n {groupedTodos.length === 0 ? (\r\n \r\n 📝 还没有待办事项,点击上方添加第一个吧!\r\n \r\n ) : (\r\n groupedTodos.map(({ date, todos }) => {\r\n const dateObj = parseISO(date);\r\n const isTodayList = isToday(dateObj);\r\n \r\n return (\r\n \r\n );\r\n })\r\n )}\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default TodoApp; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/babel-loader/e1296f11f283003da76a583f4a6ff072af7457d9d6890059ed652f5e06044ba1.json b/client/node_modules/.cache/babel-loader/e1296f11f283003da76a583f4a6ff072af7457d9d6890059ed652f5e06044ba1.json new file mode 100644 index 00000000..58675acf --- /dev/null +++ b/client/node_modules/.cache/babel-loader/e1296f11f283003da76a583f4a6ff072af7457d9d6890059ed652f5e06044ba1.json @@ -0,0 +1 @@ +{"ast":null,"code":"var _jsxFileName = \"D:\\\\aiproject\\\\goAgent\\\\todo\\\\client\\\\src\\\\components\\\\LoginForm.js\",\n _s = $RefreshSig$();\nimport React, { useState } from 'react';\nimport styled, { keyframes } from 'styled-components';\nimport { login } from '../services/api';\nimport { jsxDEV as _jsxDEV } from \"react/jsx-dev-runtime\";\nconst fadeIn = keyframes`\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n`;\nconst LoginContainer = styled.div`\n width: 100%;\n max-width: 400px;\n margin: 0 auto;\n padding: ${({\n theme\n}) => theme.spacing.xl};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n backdrop-filter: blur(10px);\n -webkit-backdrop-filter: blur(10px);\n border-radius: ${({\n theme\n}) => theme.borderRadius.xl};\n box-shadow: ${({\n theme\n}) => theme.shadows.lg};\n animation: ${fadeIn} 0.5s ease-out;\n border: 1px solid ${({\n theme\n}) => theme.colors.glass.light};\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c = LoginContainer;\nconst LoginTitle = styled.h1`\n color: ${({\n theme\n}) => theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize['3xl']};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.bold};\n text-align: center;\n margin-bottom: ${({\n theme\n}) => theme.spacing.xl};\n display: flex;\n align-items: center;\n justify-content: center;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n\n &::before {\n content: '🔒';\n font-size: 1.2em;\n }\n`;\n_c2 = LoginTitle;\nconst Form = styled.form`\n display: flex;\n flex-direction: column;\n gap: ${({\n theme\n}) => theme.spacing.lg};\n`;\n_c3 = Form;\nconst InputGroup = styled.div`\n position: relative;\n`;\n_c4 = InputGroup;\nconst Label = styled.label`\n display: block;\n margin-bottom: ${({\n theme\n}) => theme.spacing.xs};\n color: ${({\n theme\n}) => theme.colors.text.primary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.medium};\n`;\n_c5 = Label;\nconst Input = styled.input`\n width: 100%;\n padding: ${({\n theme\n}) => theme.spacing.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n border: 2px solid ${({\n theme\n}) => theme.colors.glass.light};\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n background: ${({\n theme\n}) => theme.colors.glass.light};\n color: ${({\n theme\n}) => theme.colors.text.primary};\n transition: all ${({\n theme\n}) => theme.transitions.default};\n\n &:focus {\n outline: none;\n border-color: ${({\n theme\n}) => theme.colors.primary};\n box-shadow: 0 0 0 3px ${({\n theme\n}) => theme.colors.primary}40;\n }\n\n &::placeholder {\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n }\n\n @media (prefers-color-scheme: dark) {\n background: ${({\n theme\n}) => theme.colors.glass.dark};\n border-color: ${({\n theme\n}) => theme.colors.glass.dark};\n }\n`;\n_c6 = Input;\nconst SubmitButton = styled.button`\n width: 100%;\n padding: ${({\n theme\n}) => theme.spacing.md};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.base};\n font-weight: ${({\n theme\n}) => theme.typography.fontWeight.semibold};\n color: white;\n background: ${({\n theme\n}) => theme.colors.primary};\n border: none;\n border-radius: ${({\n theme\n}) => theme.borderRadius.lg};\n cursor: pointer;\n transition: all ${({\n theme\n}) => theme.transitions.default};\n display: flex;\n align-items: center;\n justify-content: center;\n gap: ${({\n theme\n}) => theme.spacing.sm};\n\n &:hover {\n background: ${({\n theme\n}) => theme.colors.primary}dd;\n transform: translateY(-1px);\n }\n\n &:active {\n transform: translateY(0);\n }\n\n &:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n transform: none;\n }\n\n &::after {\n content: '→';\n font-size: 1.2em;\n transition: transform ${({\n theme\n}) => theme.transitions.default};\n }\n\n &:hover::after {\n transform: translateX(4px);\n }\n`;\n_c7 = SubmitButton;\nconst ErrorMessage = styled.div`\n color: ${({\n theme\n}) => theme.colors.status.error};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n text-align: center;\n margin-top: ${({\n theme\n}) => theme.spacing.sm};\n padding: ${({\n theme\n}) => theme.spacing.sm};\n background: ${({\n theme\n}) => theme.colors.status.error}20;\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n animation: ${fadeIn} 0.3s ease-out;\n`;\n_c8 = ErrorMessage;\nconst LoginHint = styled.div`\n color: ${({\n theme\n}) => theme.colors.text.secondary};\n font-size: ${({\n theme\n}) => theme.typography.fontSize.sm};\n text-align: center;\n margin-top: ${({\n theme\n}) => theme.spacing.md};\n padding: ${({\n theme\n}) => theme.spacing.sm};\n background: ${({\n theme\n}) => theme.colors.secondary}20;\n border-radius: ${({\n theme\n}) => theme.borderRadius.md};\n \n strong {\n color: ${({\n theme\n}) => theme.colors.secondary};\n }\n`;\n_c9 = LoginHint;\nfunction LoginForm({\n onLogin\n}) {\n _s();\n const [username, setUsername] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState('');\n const [isLoading, setIsLoading] = useState(false);\n const handleSubmit = async e => {\n e.preventDefault();\n setError('');\n setIsLoading(true);\n try {\n const result = await login(username, password);\n // 保存token和用户信息\n localStorage.setItem('token', result.token);\n localStorage.setItem('user', JSON.stringify(result.user));\n onLogin(result.token, result.user);\n } catch (err) {\n var _err$response, _err$response$data;\n setError(((_err$response = err.response) === null || _err$response === void 0 ? void 0 : (_err$response$data = _err$response.data) === null || _err$response$data === void 0 ? void 0 : _err$response$data.error) || '登录失败,请重试');\n } finally {\n setIsLoading(false);\n }\n };\n return /*#__PURE__*/_jsxDEV(LoginContainer, {\n children: [/*#__PURE__*/_jsxDEV(LoginTitle, {\n children: \"\\u5DE5\\u4F5C\\u5F85\\u529E\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 189,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(Form, {\n onSubmit: handleSubmit,\n children: [/*#__PURE__*/_jsxDEV(InputGroup, {\n children: [/*#__PURE__*/_jsxDEV(Label, {\n children: \"\\u7528\\u6237\\u540D\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 192,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(Input, {\n type: \"text\",\n placeholder: \"\\u8BF7\\u8F93\\u5165\\u7528\\u6237\\u540D\",\n value: username,\n onChange: e => setUsername(e.target.value),\n disabled: isLoading,\n required: true\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 193,\n columnNumber: 11\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 191,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(InputGroup, {\n children: [/*#__PURE__*/_jsxDEV(Label, {\n children: \"\\u5BC6\\u7801\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 203,\n columnNumber: 11\n }, this), /*#__PURE__*/_jsxDEV(Input, {\n type: \"password\",\n placeholder: \"\\u8BF7\\u8F93\\u5165\\u5BC6\\u7801\",\n value: password,\n onChange: e => setPassword(e.target.value),\n disabled: isLoading,\n required: true\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 204,\n columnNumber: 11\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 202,\n columnNumber: 9\n }, this), /*#__PURE__*/_jsxDEV(SubmitButton, {\n type: \"submit\",\n disabled: isLoading,\n children: isLoading ? '登录中...' : '登录'\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 213,\n columnNumber: 9\n }, this), error && /*#__PURE__*/_jsxDEV(ErrorMessage, {\n children: error\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 216,\n columnNumber: 19\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 190,\n columnNumber: 7\n }, this), /*#__PURE__*/_jsxDEV(LoginHint, {\n children: [/*#__PURE__*/_jsxDEV(\"strong\", {\n children: \"\\u7BA1\\u7406\\u5458:\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 219,\n columnNumber: 9\n }, this), \" \\u7528\\u6237\\u540D admin\\uFF0C\\u5BC6\\u7801 weiMonkey2024\", /*#__PURE__*/_jsxDEV(\"br\", {}, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 219,\n columnNumber: 57\n }, this), /*#__PURE__*/_jsxDEV(\"strong\", {\n children: \"\\u666E\\u901A\\u7528\\u6237:\"\n }, void 0, false, {\n fileName: _jsxFileName,\n lineNumber: 220,\n columnNumber: 9\n }, this), \" \\u8BF7\\u4F7F\\u7528\\u7BA1\\u7406\\u5458\\u5206\\u914D\\u7684\\u8D26\\u53F7\\u5BC6\\u7801\"]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 218,\n columnNumber: 7\n }, this)]\n }, void 0, true, {\n fileName: _jsxFileName,\n lineNumber: 188,\n columnNumber: 5\n }, this);\n}\n_s(LoginForm, \"zVDktibOVjfWgEa3dtRS5/jU2rY=\");\n_c0 = LoginForm;\nexport default LoginForm;\nvar _c, _c2, _c3, _c4, _c5, _c6, _c7, _c8, _c9, _c0;\n$RefreshReg$(_c, \"LoginContainer\");\n$RefreshReg$(_c2, \"LoginTitle\");\n$RefreshReg$(_c3, \"Form\");\n$RefreshReg$(_c4, \"InputGroup\");\n$RefreshReg$(_c5, \"Label\");\n$RefreshReg$(_c6, \"Input\");\n$RefreshReg$(_c7, \"SubmitButton\");\n$RefreshReg$(_c8, \"ErrorMessage\");\n$RefreshReg$(_c9, \"LoginHint\");\n$RefreshReg$(_c0, \"LoginForm\");","map":{"version":3,"names":["React","useState","styled","keyframes","login","jsxDEV","_jsxDEV","fadeIn","LoginContainer","div","theme","spacing","xl","colors","glass","light","borderRadius","shadows","lg","dark","_c","LoginTitle","h1","text","primary","typography","fontSize","fontWeight","bold","sm","_c2","Form","form","_c3","InputGroup","_c4","Label","label","xs","medium","_c5","Input","input","md","base","transitions","default","secondary","_c6","SubmitButton","button","semibold","_c7","ErrorMessage","status","error","_c8","LoginHint","_c9","LoginForm","onLogin","_s","username","setUsername","password","setPassword","setError","isLoading","setIsLoading","handleSubmit","e","preventDefault","result","localStorage","setItem","token","JSON","stringify","user","err","_err$response","_err$response$data","response","data","children","fileName","_jsxFileName","lineNumber","columnNumber","onSubmit","type","placeholder","value","onChange","target","disabled","required","_c0","$RefreshReg$"],"sources":["D:/aiproject/goAgent/todo/client/src/components/LoginForm.js"],"sourcesContent":["import React, { useState } from 'react';\r\nimport styled, { keyframes } from 'styled-components';\r\nimport { login } from '../services/api';\r\n\r\nconst fadeIn = keyframes`\r\n from {\r\n opacity: 0;\r\n transform: translateY(20px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n`;\r\n\r\nconst LoginContainer = styled.div`\r\n width: 100%;\r\n max-width: 400px;\r\n margin: 0 auto;\r\n padding: ${({ theme }) => theme.spacing.xl};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: ${({ theme }) => theme.borderRadius.xl};\r\n box-shadow: ${({ theme }) => theme.shadows.lg};\r\n animation: ${fadeIn} 0.5s ease-out;\r\n border: 1px solid ${({ theme }) => theme.colors.glass.light};\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst LoginTitle = styled.h1`\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize['3xl']};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.bold};\r\n text-align: center;\r\n margin-bottom: ${({ theme }) => theme.spacing.xl};\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n\r\n &::before {\r\n content: '🔒';\r\n font-size: 1.2em;\r\n }\r\n`;\r\n\r\nconst Form = styled.form`\r\n display: flex;\r\n flex-direction: column;\r\n gap: ${({ theme }) => theme.spacing.lg};\r\n`;\r\n\r\nconst InputGroup = styled.div`\r\n position: relative;\r\n`;\r\n\r\nconst Label = styled.label`\r\n display: block;\r\n margin-bottom: ${({ theme }) => theme.spacing.xs};\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.medium};\r\n`;\r\n\r\nconst Input = styled.input`\r\n width: 100%;\r\n padding: ${({ theme }) => theme.spacing.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n border: 2px solid ${({ theme }) => theme.colors.glass.light};\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n background: ${({ theme }) => theme.colors.glass.light};\r\n color: ${({ theme }) => theme.colors.text.primary};\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n\r\n &:focus {\r\n outline: none;\r\n border-color: ${({ theme }) => theme.colors.primary};\r\n box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40;\r\n }\r\n\r\n &::placeholder {\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n }\r\n\r\n @media (prefers-color-scheme: dark) {\r\n background: ${({ theme }) => theme.colors.glass.dark};\r\n border-color: ${({ theme }) => theme.colors.glass.dark};\r\n }\r\n`;\r\n\r\nconst SubmitButton = styled.button`\r\n width: 100%;\r\n padding: ${({ theme }) => theme.spacing.md};\r\n font-size: ${({ theme }) => theme.typography.fontSize.base};\r\n font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};\r\n color: white;\r\n background: ${({ theme }) => theme.colors.primary};\r\n border: none;\r\n border-radius: ${({ theme }) => theme.borderRadius.lg};\r\n cursor: pointer;\r\n transition: all ${({ theme }) => theme.transitions.default};\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: ${({ theme }) => theme.spacing.sm};\r\n\r\n &:hover {\r\n background: ${({ theme }) => theme.colors.primary}dd;\r\n transform: translateY(-1px);\r\n }\r\n\r\n &:active {\r\n transform: translateY(0);\r\n }\r\n\r\n &:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n transform: none;\r\n }\r\n\r\n &::after {\r\n content: '→';\r\n font-size: 1.2em;\r\n transition: transform ${({ theme }) => theme.transitions.default};\r\n }\r\n\r\n &:hover::after {\r\n transform: translateX(4px);\r\n }\r\n`;\r\n\r\nconst ErrorMessage = styled.div`\r\n color: ${({ theme }) => theme.colors.status.error};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n text-align: center;\r\n margin-top: ${({ theme }) => theme.spacing.sm};\r\n padding: ${({ theme }) => theme.spacing.sm};\r\n background: ${({ theme }) => theme.colors.status.error}20;\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n animation: ${fadeIn} 0.3s ease-out;\r\n`;\r\n\r\nconst LoginHint = styled.div`\r\n color: ${({ theme }) => theme.colors.text.secondary};\r\n font-size: ${({ theme }) => theme.typography.fontSize.sm};\r\n text-align: center;\r\n margin-top: ${({ theme }) => theme.spacing.md};\r\n padding: ${({ theme }) => theme.spacing.sm};\r\n background: ${({ theme }) => theme.colors.secondary}20;\r\n border-radius: ${({ theme }) => theme.borderRadius.md};\r\n \r\n strong {\r\n color: ${({ theme }) => theme.colors.secondary};\r\n }\r\n`;\r\n\r\nfunction LoginForm({ onLogin }) {\r\n const [username, setUsername] = useState('');\r\n const [password, setPassword] = useState('');\r\n const [error, setError] = useState('');\r\n const [isLoading, setIsLoading] = useState(false);\r\n\r\n const handleSubmit = async (e) => {\r\n e.preventDefault();\r\n setError('');\r\n setIsLoading(true);\r\n\r\n try {\r\n const result = await login(username, password);\r\n // 保存token和用户信息\r\n localStorage.setItem('token', result.token);\r\n localStorage.setItem('user', JSON.stringify(result.user));\r\n onLogin(result.token, result.user);\r\n } catch (err) {\r\n setError(err.response?.data?.error || '登录失败,请重试');\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n };\r\n\r\n return (\r\n \r\n 工作待办\r\n
\r\n \r\n \r\n setUsername(e.target.value)}\r\n disabled={isLoading}\r\n required\r\n />\r\n \r\n \r\n \r\n setPassword(e.target.value)}\r\n disabled={isLoading}\r\n required\r\n />\r\n \r\n \r\n {isLoading ? '登录中...' : '登录'}\r\n \r\n {error && {error}}\r\n
\r\n \r\n 管理员: 用户名 admin,密码 weiMonkey2024
\r\n 普通用户: 请使用管理员分配的账号密码\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default LoginForm; "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]} \ No newline at end of file diff --git a/client/node_modules/.cache/default-development/0.pack b/client/node_modules/.cache/default-development/0.pack index 9b2136c6..0fbb1fee 100644 Binary files a/client/node_modules/.cache/default-development/0.pack and b/client/node_modules/.cache/default-development/0.pack differ diff --git a/client/node_modules/.cache/default-development/1.pack b/client/node_modules/.cache/default-development/1.pack index b49bfbb9..7025ad48 100644 Binary files a/client/node_modules/.cache/default-development/1.pack and b/client/node_modules/.cache/default-development/1.pack differ diff --git a/client/node_modules/.cache/default-development/10.pack b/client/node_modules/.cache/default-development/10.pack index f3ba39f1..c05f6e27 100644 Binary files a/client/node_modules/.cache/default-development/10.pack and b/client/node_modules/.cache/default-development/10.pack differ diff --git a/client/node_modules/.cache/default-development/11.pack b/client/node_modules/.cache/default-development/11.pack index 3d67fb99..26cea917 100644 Binary files a/client/node_modules/.cache/default-development/11.pack and b/client/node_modules/.cache/default-development/11.pack differ diff --git a/client/node_modules/.cache/default-development/13.pack b/client/node_modules/.cache/default-development/13.pack new file mode 100644 index 00000000..7cf97bc3 Binary files /dev/null and b/client/node_modules/.cache/default-development/13.pack differ diff --git a/client/node_modules/.cache/default-development/2.pack b/client/node_modules/.cache/default-development/2.pack index 8c653e54..0cacea2b 100644 Binary files a/client/node_modules/.cache/default-development/2.pack and b/client/node_modules/.cache/default-development/2.pack differ diff --git a/client/node_modules/.cache/default-development/3.pack b/client/node_modules/.cache/default-development/3.pack index adeabe44..a99813f7 100644 Binary files a/client/node_modules/.cache/default-development/3.pack and b/client/node_modules/.cache/default-development/3.pack differ diff --git a/client/node_modules/.cache/default-development/4.pack b/client/node_modules/.cache/default-development/4.pack index 665a1cca..d77e5714 100644 Binary files a/client/node_modules/.cache/default-development/4.pack and b/client/node_modules/.cache/default-development/4.pack differ diff --git a/client/node_modules/.cache/default-development/5.pack b/client/node_modules/.cache/default-development/5.pack index d630edcc..f8d9e9f8 100644 Binary files a/client/node_modules/.cache/default-development/5.pack and b/client/node_modules/.cache/default-development/5.pack differ diff --git a/client/node_modules/.cache/default-development/6.pack b/client/node_modules/.cache/default-development/6.pack index cab211ef..686c4d7b 100644 Binary files a/client/node_modules/.cache/default-development/6.pack and b/client/node_modules/.cache/default-development/6.pack differ diff --git a/client/node_modules/.cache/default-development/7.pack b/client/node_modules/.cache/default-development/7.pack index de5f98eb..89dc9440 100644 Binary files a/client/node_modules/.cache/default-development/7.pack and b/client/node_modules/.cache/default-development/7.pack differ diff --git a/client/node_modules/.cache/default-development/8.pack b/client/node_modules/.cache/default-development/8.pack index 92d175b5..f406897f 100644 Binary files a/client/node_modules/.cache/default-development/8.pack and b/client/node_modules/.cache/default-development/8.pack differ diff --git a/client/node_modules/.cache/default-development/9.pack b/client/node_modules/.cache/default-development/9.pack index ce51e4ea..61374c89 100644 Binary files a/client/node_modules/.cache/default-development/9.pack and b/client/node_modules/.cache/default-development/9.pack differ diff --git a/client/node_modules/.cache/default-development/index.pack b/client/node_modules/.cache/default-development/index.pack index 0d810e65..ac141dc6 100644 Binary files a/client/node_modules/.cache/default-development/index.pack and b/client/node_modules/.cache/default-development/index.pack differ diff --git a/client/node_modules/.cache/default-development/index.pack.old b/client/node_modules/.cache/default-development/index.pack.old index d2bc7a6d..52605977 100644 Binary files a/client/node_modules/.cache/default-development/index.pack.old and b/client/node_modules/.cache/default-development/index.pack.old differ diff --git a/client/src/App.js b/client/src/App.js index 922016f5..9f8f99be 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -1,65 +1,107 @@ import React, { useState, useEffect } from 'react'; -import styled from 'styled-components'; +import { ThemeProvider } from 'styled-components'; +import { theme, GlobalStyle } from './styles/theme'; import LoginForm from './components/LoginForm'; import TodoApp from './components/TodoApp'; -import { checkAuth } from './services/api'; +import styled from 'styled-components'; const AppContainer = styled.div` min-height: 100vh; display: flex; - align-items: center; justify-content: center; - padding: 20px; + align-items: center; + padding: ${({ theme }) => theme.spacing.md}; + background: linear-gradient(135deg, ${({ theme }) => theme.colors.primary}20, ${({ theme }) => theme.colors.secondary}20); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + + @media (max-width: ${({ theme }) => theme.breakpoints.md}) { + padding: ${({ theme }) => theme.spacing.sm}; + } +`; + +const AppContent = styled.div` + width: 100%; + max-width: 1200px; + height: 100%; + min-height: 600px; + display: flex; + flex-direction: column; + position: relative; `; function App() { const [isAuthenticated, setIsAuthenticated] = useState(false); - const [loading, setLoading] = useState(true); + const [currentUser, setCurrentUser] = useState(null); + const [isLoading, setIsLoading] = useState(true); useEffect(() => { const token = localStorage.getItem('token'); - if (token) { - checkAuth(token) - .then(() => { - setIsAuthenticated(true); - }) - .catch(() => { - localStorage.removeItem('token'); - }) - .finally(() => { - setLoading(false); - }); - } else { - setLoading(false); + const user = localStorage.getItem('user'); + + if (token && user) { + try { + const parsedUser = JSON.parse(user); + setCurrentUser(parsedUser); + setIsAuthenticated(true); + } catch (error) { + console.error('解析用户信息失败:', error); + localStorage.removeItem('token'); + localStorage.removeItem('user'); + } } + setIsLoading(false); }, []); - const handleLogin = (token) => { + const handleLogin = (token, user) => { localStorage.setItem('token', token); + localStorage.setItem('user', JSON.stringify(user)); + setCurrentUser(user); setIsAuthenticated(true); }; const handleLogout = () => { localStorage.removeItem('token'); + localStorage.removeItem('user'); + setCurrentUser(null); setIsAuthenticated(false); }; - if (loading) { + if (isLoading) { return ( - -
加载中...
-
+ + + + +
+ 加载中... +
+
+
+
); } return ( - - {isAuthenticated ? ( - - ) : ( - - )} - + + + + + {isAuthenticated ? ( + + ) : ( + + )} + + + ); } diff --git a/client/src/components/LoginForm.js b/client/src/components/LoginForm.js index 0f57ad4e..285bb5ff 100644 --- a/client/src/components/LoginForm.js +++ b/client/src/components/LoginForm.js @@ -1,64 +1,121 @@ import React, { useState } from 'react'; -import styled from 'styled-components'; +import styled, { keyframes } from 'styled-components'; import { login } from '../services/api'; -const LoginContainer = styled.div` - background: rgba(255, 255, 255, 0.95); - backdrop-filter: blur(10px); - border-radius: 20px; - padding: 40px; - box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); - width: 100%; - max-width: 400px; - text-align: center; +const fadeIn = keyframes` + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } `; -const Title = styled.h1` - color: #333; - margin-bottom: 30px; - font-size: 28px; - font-weight: 300; +const LoginContainer = styled.div` + width: 100%; + max-width: 400px; + margin: 0 auto; + padding: ${({ theme }) => theme.spacing.xl}; + background: ${({ theme }) => theme.colors.glass.light}; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border-radius: ${({ theme }) => theme.borderRadius.xl}; + box-shadow: ${({ theme }) => theme.shadows.lg}; + animation: ${fadeIn} 0.5s ease-out; + border: 1px solid ${({ theme }) => theme.colors.glass.light}; + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + border-color: ${({ theme }) => theme.colors.glass.dark}; + } +`; + +const LoginTitle = styled.h1` + color: ${({ theme }) => theme.colors.text.primary}; + font-size: ${({ theme }) => theme.typography.fontSize['3xl']}; + font-weight: ${({ theme }) => theme.typography.fontWeight.bold}; + text-align: center; + margin-bottom: ${({ theme }) => theme.spacing.xl}; + display: flex; + align-items: center; + justify-content: center; + gap: ${({ theme }) => theme.spacing.sm}; + + &::before { + content: '🔒'; + font-size: 1.2em; + } `; const Form = styled.form` display: flex; flex-direction: column; - gap: 20px; + gap: ${({ theme }) => theme.spacing.lg}; +`; + +const InputGroup = styled.div` + position: relative; +`; + +const Label = styled.label` + display: block; + margin-bottom: ${({ theme }) => theme.spacing.xs}; + color: ${({ theme }) => theme.colors.text.primary}; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; + font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; `; const Input = styled.input` - padding: 15px 20px; - border: 2px solid #e1e5e9; - border-radius: 12px; - font-size: 16px; - transition: all 0.3s ease; - outline: none; + width: 100%; + padding: ${({ theme }) => theme.spacing.md}; + font-size: ${({ theme }) => theme.typography.fontSize.base}; + border: 2px solid ${({ theme }) => theme.colors.glass.light}; + border-radius: ${({ theme }) => theme.borderRadius.lg}; + background: ${({ theme }) => theme.colors.glass.light}; + color: ${({ theme }) => theme.colors.text.primary}; + transition: all ${({ theme }) => theme.transitions.default}; &:focus { - border-color: #667eea; - box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); + outline: none; + border-color: ${({ theme }) => theme.colors.primary}; + box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40; } &::placeholder { - color: #a0a0a0; + color: ${({ theme }) => theme.colors.text.secondary}; + } + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + border-color: ${({ theme }) => theme.colors.glass.dark}; } `; -const Button = styled.button` - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); +const SubmitButton = styled.button` + width: 100%; + padding: ${({ theme }) => theme.spacing.md}; + font-size: ${({ theme }) => theme.typography.fontSize.base}; + font-weight: ${({ theme }) => theme.typography.fontWeight.semibold}; color: white; + background: ${({ theme }) => theme.colors.primary}; border: none; - padding: 15px 20px; - border-radius: 12px; - font-size: 16px; - font-weight: 500; + border-radius: ${({ theme }) => theme.borderRadius.lg}; cursor: pointer; - transition: all 0.3s ease; - margin-top: 10px; + transition: all ${({ theme }) => theme.transitions.default}; + display: flex; + align-items: center; + justify-content: center; + gap: ${({ theme }) => theme.spacing.sm}; &:hover { - transform: translateY(-2px); - box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3); + background: ${({ theme }) => theme.colors.primary}dd; + transform: translateY(-1px); + } + + &:active { + transform: translateY(0); } &:disabled { @@ -66,66 +123,102 @@ const Button = styled.button` cursor: not-allowed; transform: none; } + + &::after { + content: '→'; + font-size: 1.2em; + transition: transform ${({ theme }) => theme.transitions.default}; + } + + &:hover::after { + transform: translateX(4px); + } `; const ErrorMessage = styled.div` - color: #e74c3c; - font-size: 14px; - margin-top: 10px; - padding: 10px; - background: rgba(231, 76, 60, 0.1); - border-radius: 8px; + color: ${({ theme }) => theme.colors.status.error}; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; + text-align: center; + margin-top: ${({ theme }) => theme.spacing.sm}; + padding: ${({ theme }) => theme.spacing.sm}; + background: ${({ theme }) => theme.colors.status.error}20; + border-radius: ${({ theme }) => theme.borderRadius.md}; + animation: ${fadeIn} 0.3s ease-out; `; -const Hint = styled.div` - color: #666; - font-size: 14px; - margin-top: 20px; - padding: 15px; - background: rgba(102, 126, 234, 0.1); - border-radius: 8px; - border-left: 4px solid #667eea; +const LoginHint = styled.div` + color: ${({ theme }) => theme.colors.text.secondary}; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; + text-align: center; + margin-top: ${({ theme }) => theme.spacing.md}; + padding: ${({ theme }) => theme.spacing.sm}; + background: ${({ theme }) => theme.colors.secondary}20; + border-radius: ${({ theme }) => theme.borderRadius.md}; + + strong { + color: ${({ theme }) => theme.colors.secondary}; + } `; function LoginForm({ onLogin }) { + const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); - const [loading, setLoading] = useState(false); const [error, setError] = useState(''); + const [isLoading, setIsLoading] = useState(false); const handleSubmit = async (e) => { e.preventDefault(); - setLoading(true); setError(''); + setIsLoading(true); try { - const response = await login(password); - onLogin(response.token); + const result = await login(username, password); + // 保存token和用户信息 + localStorage.setItem('token', result.token); + localStorage.setItem('user', JSON.stringify(result.user)); + onLogin(result.token, result.user); } catch (err) { setError(err.response?.data?.error || '登录失败,请重试'); } finally { - setLoading(false); + setIsLoading(false); } }; return ( - 工作待办 + 工作待办
- setPassword(e.target.value)} - required - /> - + + + setUsername(e.target.value)} + disabled={isLoading} + required + /> + + + + setPassword(e.target.value)} + disabled={isLoading} + required + /> + + + {isLoading ? '登录中...' : '登录'} + + {error && {error}}
- {error && {error}} - - 💡 提示:首次使用需要输入访问密码 - + + {/* 管理员: 用户名 admin,密码 weiMonkey2024
*/} + 普通用户: 请使用管理员分配的账号密码 +
); } diff --git a/client/src/components/TodoApp.js b/client/src/components/TodoApp.js index e213fee0..7885dc18 100644 --- a/client/src/components/TodoApp.js +++ b/client/src/components/TodoApp.js @@ -6,6 +6,7 @@ import TodoForm from './TodoForm'; import TodoList from './TodoList'; import HistoryTodos from './HistoryTodos'; import SuspendedTodos from './SuspendedTodos'; +import UserManagement from './UserManagement'; const AppContainer = styled.div` background: rgba(255, 255, 255, 0.95); @@ -29,6 +30,12 @@ const Header = styled.div` border-bottom: 2px solid #f0f0f0; `; +const TitleSection = styled.div` + display: flex; + flex-direction: column; + gap: 8px; +`; + const Title = styled.h1` color: #333; font-size: 32px; @@ -36,16 +43,61 @@ const Title = styled.h1` margin: 0; `; +const UserInfo = styled.div` + color: #666; + font-size: 14px; + display: flex; + align-items: center; + gap: 8px; + + .username { + font-weight: 500; + color: #667eea; + } + + .role { + padding: 2px 8px; + border-radius: 12px; + font-size: 12px; + font-weight: 500; + } + + .admin { + background: rgba(255, 152, 0, 0.1); + color: #ff9800; + } + + .user { + background: rgba(102, 126, 234, 0.1); + color: #667eea; + } +`; + const HeaderActions = styled.div` display: flex; gap: 12px; align-items: center; + flex-wrap: wrap; + + @media (max-width: 768px) { + flex-direction: column; + align-items: stretch; + gap: 8px; + } `; -const MigratePendingButton = styled.button` - background: rgba(255, 152, 0, 0.1); - color: #ff9800; - border: 2px solid rgba(255, 152, 0, 0.2); +const ActionButton = styled.button` + background: ${({ variant, theme }) => { + switch (variant) { + case 'primary': return theme?.colors?.primary || '#667eea'; + case 'warning': return '#ff9800'; + case 'success': return '#00B894'; + case 'danger': return '#e74c3c'; + default: return 'transparent'; + } + }}; + color: ${({ variant }) => variant === 'default' ? '#666' : 'white'}; + border: ${({ variant }) => variant === 'default' ? '2px solid #e1e5e9' : 'none'}; padding: 10px 20px; border-radius: 8px; font-size: 14px; @@ -54,85 +106,27 @@ const MigratePendingButton = styled.button` display: flex; align-items: center; gap: 8px; + white-space: nowrap; &:hover { - background: rgba(255, 152, 0, 0.15); - border-color: #ff9800; transform: translateY(-1px); + ${({ variant }) => { + if (variant === 'default') { + return ` + border-color: #667eea; + color: #667eea; + `; + } + return 'opacity: 0.9;'; + }} } &::before { - content: '📦'; + content: ${({ icon }) => icon ? `'${icon}'` : 'none'}; font-size: 16px; } `; -const SuspendedButton = styled.button` - background: rgba(255, 152, 0, 0.1); - color: #ff9800; - border: 2px solid rgba(255, 152, 0, 0.2); - padding: 10px 20px; - border-radius: 8px; - font-size: 14px; - cursor: pointer; - transition: all 0.3s ease; - display: flex; - align-items: center; - gap: 8px; - - &:hover { - background: rgba(255, 152, 0, 0.15); - border-color: #ff9800; - transform: translateY(-1px); - } - - &::before { - content: '⏸️'; - font-size: 16px; - } -`; - -const HistoryButton = styled.button` - background: rgba(102, 126, 234, 0.1); - color: #667eea; - border: 2px solid rgba(102, 126, 234, 0.2); - padding: 10px 20px; - border-radius: 8px; - font-size: 14px; - cursor: pointer; - transition: all 0.3s ease; - display: flex; - align-items: center; - gap: 8px; - - &:hover { - background: rgba(102, 126, 234, 0.15); - border-color: #667eea; - transform: translateY(-1px); - } - - &::before { - content: '📚'; - font-size: 16px; - } -`; - -const LogoutButton = styled.button` - background: transparent; - color: #666; - border: 2px solid #e1e5e9; - padding: 10px 20px; - border-radius: 8px; - font-size: 14px; - cursor: pointer; - transition: all 0.3s ease; - - &:hover { - border-color: #667eea; - color: #667eea; - } -`; - const Content = styled.div` display: flex; flex-direction: column; @@ -156,12 +150,13 @@ const EmptyMessage = styled.div` border: 2px dashed #e1e5e9; `; -function TodoApp({ onLogout }) { +function TodoApp({ onLogout, currentUser }) { const [todos, setTodos] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [showHistory, setShowHistory] = useState(false); const [showSuspended, setShowSuspended] = useState(false); + const [showUserManagement, setShowUserManagement] = useState(false); const [successMessage, setSuccessMessage] = useState(''); useEffect(() => { @@ -292,6 +287,15 @@ function TodoApp({ onLogout }) { const groupedTodos = groupTodosByDate(todos); + // 如果正在显示用户管理视图 + if (showUserManagement) { + return ( + + setShowUserManagement(false)} /> + + ); + } + // 如果正在显示历史视图 if (showHistory) { return ( @@ -321,18 +325,54 @@ function TodoApp({ onLogout }) { return (
- 工作待办 + + 工作待办 + {currentUser && ( + + 欢迎,{currentUser.username} + + {currentUser.is_admin ? '管理员' : '用户'} + + + )} + - + 迁移未完成 - - setShowSuspended(true)}> + + setShowSuspended(true)} + > 挂起待办 - - setShowHistory(true)}> + + setShowHistory(true)} + > 历史记录 - - 退出 + + {currentUser?.is_admin && ( + setShowUserManagement(true)} + > + 用户管理 + + )} + + 退出 +
diff --git a/client/src/components/TodoItem.js b/client/src/components/TodoItem.js index 095e2fd2..daf5954f 100644 --- a/client/src/components/TodoItem.js +++ b/client/src/components/TodoItem.js @@ -1,219 +1,344 @@ -import React from 'react'; -import styled from 'styled-components'; +import React, { useState } from 'react'; +import styled, { keyframes } from 'styled-components'; -const ItemContainer = styled.div` - display: flex; - align-items: center; - padding: 20px; - background: ${props => props.completed ? '#f8f9fa' : 'white'}; - border: 2px solid ${props => props.completed ? '#e9ecef' : '#f0f0f0'}; - border-radius: 16px; - transition: all 0.3s ease; - cursor: ${props => props.isHistory ? 'default' : 'pointer'}; - opacity: ${props => props.completed ? 0.7 : 1}; - - &:hover { - border-color: ${props => props.completed ? '#e9ecef' : (props.isHistory ? '#f0f0f0' : '#667eea')}; - box-shadow: ${props => (props.completed || props.isHistory) ? 'none' : '0 6px 16px rgba(102, 126, 234, 0.15)'}; - transform: ${props => (props.completed || props.isHistory) ? 'none' : 'translateY(-2px)'}; +const slideIn = keyframes` + from { + opacity: 0; + transform: translateX(-10px); + } + to { + opacity: 1; + transform: translateX(0); } `; -const PriorityIndicator = styled.div` - width: 16px; - height: 16px; - border-radius: 50%; - background-color: ${props => props.color}; - margin-right: 20px; - flex-shrink: 0; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); +const fadeIn = keyframes` + from { + opacity: 0; + } + to { + opacity: 1; + } `; -const TodoContent = styled.div` +const scaleIn = keyframes` + from { + transform: scale(0.95); + } + to { + transform: scale(1); + } +`; + +const ItemContainer = styled.div` + background: ${({ theme }) => theme.colors.glass.light}; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border-radius: ${({ theme }) => theme.borderRadius.lg}; + padding: ${({ theme }) => theme.spacing.lg}; + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing.md}; + transition: all ${({ theme }) => theme.transitions.default}; + border: 1px solid ${({ theme }) => theme.colors.glass.light}; + animation: ${slideIn} 0.3s ease-out; + position: relative; + overflow: hidden; + cursor: pointer; + + &:hover { + transform: translateY(-2px); + box-shadow: ${({ theme }) => theme.shadows.md}; + } + + &:active { + transform: translateY(0); + box-shadow: ${({ theme }) => theme.shadows.sm}; + } + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + border-color: ${({ theme }) => theme.colors.glass.dark}; + } + + @media (max-width: ${({ theme }) => theme.breakpoints.md}) { + padding: ${({ theme }) => theme.spacing.md}; + } +`; + +const Checkbox = styled.input` + appearance: none; + width: 24px; + height: 24px; + border: 2px solid ${({ theme }) => theme.colors.primary}; + border-radius: ${({ theme }) => theme.borderRadius.md}; + cursor: pointer; + position: relative; + transition: all ${({ theme }) => theme.transitions.default}; + flex-shrink: 0; + + &:checked { + background: ${({ theme }) => theme.colors.primary}; + border-color: ${({ theme }) => theme.colors.primary}; + } + + &:checked::after { + content: '✓'; + position: absolute; + color: white; + font-size: 16px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + animation: ${fadeIn} 0.2s ease-out; + } + + &:hover { + transform: scale(1.1); + } + + &:focus { + outline: none; + box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40; + } +`; + +const Content = styled.div` flex: 1; display: flex; flex-direction: column; - gap: 6px; + gap: ${({ theme }) => theme.spacing.xs}; + min-width: 0; // 防止内容溢出 `; -const TodoTitle = styled.span` - font-size: 17px; - color: ${props => props.completed ? '#6c757d' : '#333'}; - text-decoration: ${props => props.completed ? 'line-through' : 'none'}; - font-weight: 500; +const Title = styled.span` + color: ${({ theme, completed }) => completed ? theme.colors.text.secondary : theme.colors.text.primary}; + font-size: ${({ theme }) => theme.typography.fontSize.base}; + font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; + text-decoration: ${({ completed }) => completed ? 'line-through' : 'none'}; + transition: all ${({ theme }) => theme.transitions.default}; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +`; + +const Description = styled.p` + color: ${({ theme }) => theme.colors.text.secondary}; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; + margin: 0; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; line-height: 1.4; `; -const PriorityLabel = styled.span` - font-size: 13px; - color: ${props => props.color}; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.5px; -`; - -const ActionButtons = styled.div` - display: flex; +const PriorityBadge = styled.span` + padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.sm}`}; + border-radius: ${({ theme }) => theme.borderRadius.full}; + font-size: ${({ theme }) => theme.typography.fontSize.xs}; + font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; + background: ${({ theme, priority }) => theme.colors.priority[priority]}20; + color: ${({ theme, priority }) => theme.colors.priority[priority]}; + transition: all ${({ theme }) => theme.transitions.default}; + display: inline-flex; align-items: center; - gap: 8px; -`; + gap: ${({ theme }) => theme.spacing.xs}; -const CheckButton = styled.button` - width: 28px; - height: 28px; - border-radius: 50%; - border: 2px solid ${props => props.completed ? '#28a745' : '#dee2e6'}; - background: ${props => props.completed ? '#28a745' : 'white'}; - cursor: ${props => props.isHistory ? 'default' : 'pointer'}; - transition: all 0.3s ease; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; - opacity: ${props => props.isHistory ? 0.6 : 1}; + &::before { + content: ${({ priority }) => { + switch (priority) { + case 'urgent': return '"🚨"'; + case 'high': return '"🔥"'; + case 'medium': return '"⚡"'; + case 'low': return '"🐢"'; + default: return '"📌"'; + } + }}; + font-size: 1.1em; + } &:hover { - border-color: ${props => props.isHistory ? (props.completed ? '#28a745' : '#dee2e6') : '#28a745'}; - background: ${props => props.completed ? '#28a745' : (props.isHistory ? 'white' : 'rgba(40, 167, 69, 0.1)')}; - transform: ${props => props.isHistory ? 'none' : 'scale(1.1)'}; - } - - &::after { - content: '✓'; - color: white; - font-size: 16px; - font-weight: bold; - opacity: ${props => props.completed ? 1 : 0}; - transition: opacity 0.3s ease; + transform: translateY(-1px); + background: ${({ theme, priority }) => theme.colors.priority[priority]}30; } `; -const DeleteButton = styled.button` - width: 28px; - height: 28px; - border-radius: 50%; - border: 2px solid #e74c3c; - background: white; +const ButtonGroup = styled.div` + display: flex; + gap: ${({ theme }) => theme.spacing.sm}; + opacity: 0; + transition: all ${({ theme }) => theme.transitions.default}; + position: absolute; + right: ${({ theme }) => theme.spacing.lg}; + top: 50%; + transform: translateY(-50%); + + ${ItemContainer}:hover & { + opacity: 1; + } + + @media (max-width: ${({ theme }) => theme.breakpoints.md}) { + opacity: 1; + position: static; + transform: none; + } +`; + +const ActionButton = styled.button` + background: none; + border: none; + padding: ${({ theme }) => theme.spacing.sm}; cursor: pointer; - transition: all 0.3s ease; + color: ${({ theme }) => theme.colors.text.secondary}; + border-radius: ${({ theme }) => theme.borderRadius.md}; + transition: all ${({ theme }) => theme.transitions.default}; display: flex; align-items: center; justify-content: center; - flex-shrink: 0; + font-size: 1.2em; &:hover { - background: #e74c3c; - transform: scale(1.1); + background: ${({ theme }) => theme.colors.glass.light}; + color: ${({ theme }) => theme.colors.primary}; + transform: translateY(-1px); } - &::after { - content: '×'; - color: #e74c3c; - font-size: 18px; - font-weight: bold; - transition: color 0.3s ease; + &:active { + transform: translateY(0); } - &:hover::after { - color: white; + &:focus { + outline: none; + box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40; + } + + @media (prefers-color-scheme: dark) { + &:hover { + background: ${({ theme }) => theme.colors.glass.dark}; + } } `; -const SuspendButton = styled.button` - width: 28px; - height: 28px; - border-radius: 50%; - border: 2px solid #ff9800; - background: white; - cursor: pointer; - transition: all 0.3s ease; +const StatusBadge = styled.span` + position: absolute; + top: ${({ theme }) => theme.spacing.sm}; + right: ${({ theme }) => theme.spacing.sm}; + padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.sm}`}; + border-radius: ${({ theme }) => theme.borderRadius.full}; + font-size: ${({ theme }) => theme.typography.fontSize.xs}; + font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; + background: ${({ theme, status }) => theme.colors.status[status]}20; + color: ${({ theme, status }) => theme.colors.status[status]}; + animation: ${fadeIn} 0.3s ease-out; display: flex; align-items: center; - justify-content: center; - flex-shrink: 0; + gap: ${({ theme }) => theme.spacing.xs}; - &:hover { - background: #ff9800; - transform: scale(1.1); - } - - &::after { - content: '⏸'; - color: #ff9800; - font-size: 12px; - font-weight: bold; - transition: color 0.3s ease; - } - - &:hover::after { - color: white; + &::before { + content: ${({ status }) => { + switch (status) { + case 'warning': return '"⏸️"'; + case 'success': return '"✅"'; + case 'error': return '"❌"'; + default: return '"📌"'; + } + }}; + font-size: 1.1em; } `; -const priorityConfig = { - low: { color: '#95a5a6', label: '低' }, - medium: { color: '#3498db', label: '中' }, - high: { color: '#e67e22', label: '高' }, - urgent: { color: '#e74c3c', label: '急' } -}; +const Tooltip = styled.div` + position: absolute; + bottom: 100%; + left: 50%; + transform: translateX(-50%); + padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.sm}`}; + background: ${({ theme }) => theme.colors.glass.dark}; + color: ${({ theme }) => theme.colors.text.light}; + border-radius: ${({ theme }) => theme.borderRadius.md}; + font-size: ${({ theme }) => theme.typography.fontSize.xs}; + white-space: nowrap; + opacity: 0; + visibility: hidden; + transition: all ${({ theme }) => theme.transitions.default}; + pointer-events: none; + z-index: 1000; -function TodoItem({ todo, onToggle, onDelete, onSuspend, isHistory = false, isToday = false }) { - const priority = priorityConfig[todo.priority] || priorityConfig.medium; + ${ActionButton}:hover & { + opacity: 1; + visibility: visible; + transform: translateX(-50%) translateY(-4px); + } +`; - const handleClick = (e) => { - // 如果点击的是删除或挂起按钮,不触发toggle - if (e.target.closest('button[data-action="delete"]') || e.target.closest('button[data-action="suspend"]')) { - return; - } - if (!isHistory) { - onToggle(todo.id, !todo.completed); - } +function TodoItem({ todo, onToggle, onDelete, onSuspend, isHistory, isToday }) { + const [isHovered, setIsHovered] = useState(false); + + const getPriorityLabel = (priority) => { + const labels = { + low: '低优先级', + medium: '中优先级', + high: '高优先级', + urgent: '紧急' + }; + return labels[priority] || priority; + }; + + const handleToggle = (e) => { + e.stopPropagation(); + onToggle(todo.id, !todo.completed); }; const handleDelete = (e) => { e.stopPropagation(); - if (onDelete) { - onDelete(todo.id); - } + onDelete(todo.id); }; const handleSuspend = (e) => { e.stopPropagation(); - if (onSuspend) { - onSuspend(todo.id); - } + onSuspend(todo.id); }; return ( - - - - - + setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + onClick={handleToggle} + > + + + {todo.title} - </TodoTitle> - <PriorityLabel color={priority.color}> - {priority.label}优先级 - </PriorityLabel> - </TodoContent> - - <ActionButtons> - <CheckButton completed={todo.completed} isHistory={isHistory} /> - {isToday && !isHistory && ( - <> - <SuspendButton - onClick={handleSuspend} - data-action="suspend" - title="挂起待办事项" - /> - <DeleteButton - onClick={handleDelete} - data-action="delete" - title="删除待办事项" - /> - </> + + {todo.description && ( + {todo.description} )} - + + {getPriorityLabel(todo.priority)} + + + + {isToday && !todo.completed && !todo.suspended && ( + + ⏸️ + 挂起任务 + + )} + {!isHistory && ( + + 🗑️ + 删除任务 + + )} + + {todo.suspended && ( + 已挂起 + )} ); } diff --git a/client/src/components/TodoList.js b/client/src/components/TodoList.js index a4d60e19..7f7ff0b7 100644 --- a/client/src/components/TodoList.js +++ b/client/src/components/TodoList.js @@ -1,44 +1,130 @@ import React from 'react'; -import styled from 'styled-components'; +import styled, { keyframes } from 'styled-components'; import TodoItem from './TodoItem'; +const fadeIn = keyframes` + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +`; + const ListContainer = styled.div` - background: white; - border-radius: 20px; - padding: 30px; - box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08); - border: 1px solid #f0f0f0; + background: ${({ theme }) => theme.colors.glass.light}; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border-radius: ${({ theme }) => theme.borderRadius.xl}; + padding: ${({ theme }) => theme.spacing.xl}; + box-shadow: ${({ theme }) => theme.shadows.lg}; + border: 1px solid ${({ theme }) => theme.colors.glass.light}; + animation: ${fadeIn} 0.5s ease-out; + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + border-color: ${({ theme }) => theme.colors.glass.dark}; + } + + @media (max-width: ${({ theme }) => theme.breakpoints.md}) { + padding: ${({ theme }) => theme.spacing.lg}; + border-radius: ${({ theme }) => theme.borderRadius.lg}; + } `; const DateHeader = styled.div` display: flex; align-items: center; - margin-bottom: 25px; - padding-bottom: 15px; - border-bottom: 2px solid #f8f9fa; + justify-content: space-between; + margin-bottom: ${({ theme }) => theme.spacing.xl}; + padding-bottom: ${({ theme }) => theme.spacing.md}; + border-bottom: 2px solid ${({ theme }) => theme.colors.glass.light}; + + @media (prefers-color-scheme: dark) { + border-bottom-color: ${({ theme }) => theme.colors.glass.dark}; + } + + @media (max-width: ${({ theme }) => theme.breakpoints.md}) { + margin-bottom: ${({ theme }) => theme.spacing.lg}; + padding-bottom: ${({ theme }) => theme.spacing.sm}; + } `; const DateLabel = styled.h3` - color: #333; - font-size: 20px; - font-weight: 600; + color: ${({ theme }) => theme.colors.text.primary}; + font-size: ${({ theme }) => theme.typography.fontSize.xl}; + font-weight: ${({ theme }) => theme.typography.fontWeight.semibold}; margin: 0; - margin-right: 16px; + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing.sm}; + + &::before { + content: '📅'; + font-size: 1.2em; + } + + @media (max-width: ${({ theme }) => theme.breakpoints.md}) { + font-size: ${({ theme }) => theme.typography.fontSize.lg}; + } `; -const TodoCount = styled.span` - background: rgba(102, 126, 234, 0.1); - color: #667eea; - padding: 6px 16px; - border-radius: 20px; - font-size: 14px; - font-weight: 600; +const TodoCount = styled.div` + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing.xs}; + padding: ${({ theme }) => `${theme.spacing.xs} ${theme.spacing.md}`}; + background: ${({ theme }) => theme.colors.primary}20; + color: ${({ theme }) => theme.colors.primary}; + border-radius: ${({ theme }) => theme.borderRadius.full}; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; + font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; + transition: all ${({ theme }) => theme.transitions.default}; + + &:hover { + background: ${({ theme }) => theme.colors.primary}30; + transform: translateY(-1px); + } + + &::before { + content: '📊'; + font-size: 1.1em; + } `; const TodoItems = styled.div` display: flex; flex-direction: column; - gap: 16px; + gap: ${({ theme }) => theme.spacing.md}; + + @media (max-width: ${({ theme }) => theme.breakpoints.md}) { + gap: ${({ theme }) => theme.spacing.sm}; + } +`; + +const EmptyMessage = styled.div` + text-align: center; + padding: ${({ theme }) => theme.spacing.xl}; + color: ${({ theme }) => theme.colors.text.secondary}; + font-size: ${({ theme }) => theme.typography.fontSize.lg}; + background: ${({ theme }) => theme.colors.glass.light}; + border-radius: ${({ theme }) => theme.borderRadius.lg}; + border: 2px dashed ${({ theme }) => theme.colors.glass.light}; + animation: ${fadeIn} 0.5s ease-out; + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + border-color: ${({ theme }) => theme.colors.glass.dark}; + } + + &::before { + content: '📝'; + font-size: 2em; + display: block; + margin-bottom: ${({ theme }) => theme.spacing.sm}; + } `; function TodoList({ dateLabel, todos, onToggleTodo, onDeleteTodo, onSuspendTodo, isHistory = false, isToday = false }) { @@ -55,17 +141,23 @@ function TodoList({ dateLabel, todos, onToggleTodo, onDeleteTodo, onSuspendTodo, - {todos.map(todo => ( - - ))} + {todos.length === 0 ? ( + + 暂无待办事项 + + ) : ( + todos.map(todo => ( + + )) + )} ); diff --git a/client/src/components/UserManagement.js b/client/src/components/UserManagement.js new file mode 100644 index 00000000..5fd22bd8 --- /dev/null +++ b/client/src/components/UserManagement.js @@ -0,0 +1,369 @@ +import React, { useState, useEffect } from 'react'; +import styled, { keyframes } from 'styled-components'; +import { getUsers, registerUser } from '../services/api'; + +const fadeIn = keyframes` + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +`; + +const UserManagementContainer = styled.div` + background: ${({ theme }) => theme.colors.glass.light}; + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + border-radius: ${({ theme }) => theme.borderRadius.xl}; + padding: ${({ theme }) => theme.spacing.xl}; + box-shadow: ${({ theme }) => theme.shadows.lg}; + border: 1px solid ${({ theme }) => theme.colors.glass.light}; + animation: ${fadeIn} 0.5s ease-out; + max-width: 800px; + margin: 0 auto; + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + border-color: ${({ theme }) => theme.colors.glass.dark}; + } +`; + +const Header = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: ${({ theme }) => theme.spacing.xl}; + padding-bottom: ${({ theme }) => theme.spacing.lg}; + border-bottom: 2px solid ${({ theme }) => theme.colors.glass.light}; + + @media (prefers-color-scheme: dark) { + border-bottom-color: ${({ theme }) => theme.colors.glass.dark}; + } +`; + +const Title = styled.h2` + color: ${({ theme }) => theme.colors.text.primary}; + font-size: ${({ theme }) => theme.typography.fontSize['2xl']}; + font-weight: ${({ theme }) => theme.typography.fontWeight.semibold}; + margin: 0; + display: flex; + align-items: center; + gap: ${({ theme }) => theme.spacing.sm}; + + &::before { + content: '👥'; + font-size: 1.2em; + } +`; + +const BackButton = styled.button` + background: ${({ theme }) => theme.colors.glass.light}; + color: ${({ theme }) => theme.colors.text.primary}; + border: 2px solid ${({ theme }) => theme.colors.glass.light}; + padding: ${({ theme }) => `${theme.spacing.sm} ${theme.spacing.lg}`}; + border-radius: ${({ theme }) => theme.borderRadius.lg}; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; + cursor: pointer; + transition: all ${({ theme }) => theme.transitions.default}; + + &:hover { + background: ${({ theme }) => theme.colors.primary}; + color: white; + border-color: ${({ theme }) => theme.colors.primary}; + transform: translateY(-1px); + } + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + border-color: ${({ theme }) => theme.colors.glass.dark}; + } +`; + +const AddUserForm = styled.form` + display: flex; + gap: ${({ theme }) => theme.spacing.md}; + margin-bottom: ${({ theme }) => theme.spacing.xl}; + padding: ${({ theme }) => theme.spacing.lg}; + background: ${({ theme }) => theme.colors.glass.light}; + border-radius: ${({ theme }) => theme.borderRadius.lg}; + border: 2px dashed ${({ theme }) => theme.colors.primary}40; + + @media (max-width: ${({ theme }) => theme.breakpoints.md}) { + flex-direction: column; + } + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + } +`; + +const InputGroup = styled.div` + flex: 1; + display: flex; + flex-direction: column; + gap: ${({ theme }) => theme.spacing.xs}; +`; + +const Label = styled.label` + color: ${({ theme }) => theme.colors.text.primary}; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; + font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; +`; + +const Input = styled.input` + padding: ${({ theme }) => theme.spacing.md}; + font-size: ${({ theme }) => theme.typography.fontSize.base}; + border: 2px solid ${({ theme }) => theme.colors.glass.light}; + border-radius: ${({ theme }) => theme.borderRadius.md}; + background: ${({ theme }) => theme.colors.glass.light}; + color: ${({ theme }) => theme.colors.text.primary}; + transition: all ${({ theme }) => theme.transitions.default}; + + &:focus { + outline: none; + border-color: ${({ theme }) => theme.colors.primary}; + box-shadow: 0 0 0 3px ${({ theme }) => theme.colors.primary}40; + } + + &::placeholder { + color: ${({ theme }) => theme.colors.text.secondary}; + } + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + border-color: ${({ theme }) => theme.colors.glass.dark}; + } +`; + +const AddButton = styled.button` + background: ${({ theme }) => theme.colors.primary}; + color: white; + border: none; + padding: ${({ theme }) => `${theme.spacing.md} ${theme.spacing.lg}`}; + border-radius: ${({ theme }) => theme.borderRadius.md}; + font-size: ${({ theme }) => theme.typography.fontSize.base}; + font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; + cursor: pointer; + transition: all ${({ theme }) => theme.transitions.default}; + align-self: end; + + &:hover { + background: ${({ theme }) => theme.colors.primary}dd; + transform: translateY(-1px); + } + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + transform: none; + } +`; + +const UserList = styled.div` + display: flex; + flex-direction: column; + gap: ${({ theme }) => theme.spacing.md}; +`; + +const UserItem = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + padding: ${({ theme }) => theme.spacing.lg}; + background: ${({ theme }) => theme.colors.glass.light}; + border-radius: ${({ theme }) => theme.borderRadius.lg}; + border: 1px solid ${({ theme }) => theme.colors.glass.light}; + transition: all ${({ theme }) => theme.transitions.default}; + + &:hover { + transform: translateY(-1px); + box-shadow: ${({ theme }) => theme.shadows.md}; + } + + @media (prefers-color-scheme: dark) { + background: ${({ theme }) => theme.colors.glass.dark}; + border-color: ${({ theme }) => theme.colors.glass.dark}; + } +`; + +const UserInfo = styled.div` + display: flex; + flex-direction: column; + gap: ${({ theme }) => theme.spacing.xs}; +`; + +const Username = styled.span` + color: ${({ theme }) => theme.colors.text.primary}; + font-size: ${({ theme }) => theme.typography.fontSize.lg}; + font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; +`; + +const UserRole = styled.span` + color: ${({ theme, isAdmin }) => isAdmin ? theme.colors.status.warning : theme.colors.text.secondary}; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; + font-weight: ${({ theme }) => theme.typography.fontWeight.medium}; +`; + +const UserDate = styled.span` + color: ${({ theme }) => theme.colors.text.secondary}; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; +`; + +const Message = styled.div` + padding: ${({ theme }) => theme.spacing.md}; + border-radius: ${({ theme }) => theme.borderRadius.md}; + margin-bottom: ${({ theme }) => theme.spacing.lg}; + text-align: center; + font-size: ${({ theme }) => theme.typography.fontSize.sm}; + animation: ${fadeIn} 0.3s ease-out; + + ${({ type, theme }) => { + if (type === 'success') { + return ` + background: ${theme.colors.status.success}20; + color: ${theme.colors.status.success}; + border: 1px solid ${theme.colors.status.success}40; + `; + } + if (type === 'error') { + return ` + background: ${theme.colors.status.error}20; + color: ${theme.colors.status.error}; + border: 1px solid ${theme.colors.status.error}40; + `; + } + return ''; + }} +`; + +function UserManagement({ onBack }) { + const [users, setUsers] = useState([]); + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + const [loading, setLoading] = useState(true); + const [submitting, setSubmitting] = useState(false); + const [message, setMessage] = useState({ text: '', type: '' }); + + useEffect(() => { + loadUsers(); + }, []); + + const loadUsers = async () => { + try { + setLoading(true); + const userData = await getUsers(); + setUsers(userData); + } catch (error) { + setMessage({ text: '加载用户列表失败', type: 'error' }); + } finally { + setLoading(false); + } + }; + + const handleSubmit = async (e) => { + e.preventDefault(); + if (!username.trim() || !password.trim()) { + setMessage({ text: '用户名和密码不能为空', type: 'error' }); + return; + } + + setSubmitting(true); + try { + await registerUser(username.trim(), password); + setMessage({ text: '用户添加成功', type: 'success' }); + setUsername(''); + setPassword(''); + await loadUsers(); + } catch (error) { + setMessage({ + text: error.response?.data?.error || '添加用户失败', + type: 'error' + }); + } finally { + setSubmitting(false); + } + + // 清除消息 + setTimeout(() => setMessage({ text: '', type: '' }), 5000); + }; + + const formatDate = (dateString) => { + return new Date(dateString).toLocaleDateString('zh-CN', { + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }); + }; + + return ( + +
+ 用户管理 + 返回 +
+ + {message.text && ( + {message.text} + )} + + + + + setUsername(e.target.value)} + disabled={submitting} + required + /> + + + + setPassword(e.target.value)} + disabled={submitting} + required + /> + + + {submitting ? '添加中...' : '添加用户'} + + + + + {loading ? ( +
+ 加载中... +
+ ) : users.length === 0 ? ( +
+ 暂无用户 +
+ ) : ( + users.map(user => ( + + + {user.username} + + {user.is_admin ? '管理员' : '普通用户'} + + 创建于 {formatDate(user.created_at)} + + + )) + )} +
+
+ ); +} + +export default UserManagement; \ No newline at end of file diff --git a/client/src/services/api.js b/client/src/services/api.js index d476720c..ef3b07b8 100644 --- a/client/src/services/api.js +++ b/client/src/services/api.js @@ -1,13 +1,13 @@ import axios from 'axios'; -const API_BASE_URL = '/api'; +const API_URL = 'http://localhost:5000/api'; // 创建axios实例 const api = axios.create({ - baseURL: API_BASE_URL, + baseURL: API_URL, }); -// 添加请求拦截器,自动添加token +// 请求拦截器,自动添加token api.interceptors.request.use((config) => { const token = localStorage.getItem('token'); if (token) { @@ -16,17 +16,21 @@ api.interceptors.request.use((config) => { return config; }); -// 登录验证 -export const login = async (password) => { - const response = await api.post('/auth', { password }); +// 用户登录 +export const login = async (username, password) => { + const response = await api.post('/auth/login', { username, password }); return response.data; }; -// 检查认证状态 -export const checkAuth = async (token) => { - const response = await api.get('/todos', { - headers: { Authorization: `Bearer ${token}` } - }); +// 管理员注册新用户 +export const registerUser = async (username, password) => { + const response = await api.post('/auth/register', { username, password }); + return response.data; +}; + +// 获取所有用户(仅管理员) +export const getUsers = async () => { + const response = await api.get('/users'); return response.data; }; @@ -42,6 +46,12 @@ export const getHistoryTodos = async () => { return response.data; }; +// 获取挂起的待办事项 +export const getSuspendedTodos = async () => { + const response = await api.get('/todos/suspended'); + return response.data; +}; + // 迁移历史未完成待办到今天 export const migratePendingTodos = async () => { const response = await api.post('/todos/migrate-pending'); @@ -54,12 +64,6 @@ export const suspendTodo = async (id) => { return response.data; }; -// 获取挂起的待办事项 -export const getSuspendedTodos = async () => { - const response = await api.get('/todos/suspended'); - return response.data; -}; - // 恢复挂起的待办事项 export const resumeTodo = async (id) => { const response = await api.put(`/todos/${id}/resume`); diff --git a/client/src/styles/theme.js b/client/src/styles/theme.js new file mode 100644 index 00000000..7d8e90da --- /dev/null +++ b/client/src/styles/theme.js @@ -0,0 +1,149 @@ +import { createGlobalStyle } from 'styled-components'; + +export const theme = { + colors: { + primary: '#6C5CE7', // 主色:柔和紫 + secondary: '#00B894', // 辅助色:生态绿 + background: { + light: 'rgba(255, 255, 255, 0.95)', + dark: 'rgba(30, 30, 30, 0.95)', + }, + text: { + primary: '#2D3436', + secondary: '#636E72', + light: '#FFFFFF', + }, + priority: { + low: '#95A5A6', + medium: '#3498DB', + high: '#E67E22', + urgent: '#E74C3C', + }, + status: { + success: '#00B894', + warning: '#FDCB6E', + error: '#E74C3C', + }, + glass: { + light: 'rgba(255, 255, 255, 0.7)', + dark: 'rgba(30, 30, 30, 0.7)', + } + }, + typography: { + fontFamily: { + pc: 'Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', + mobile: 'SF Pro Rounded, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', + }, + fontSize: { + xs: '0.75rem', + sm: '0.875rem', + base: '1rem', + lg: '1.125rem', + xl: '1.25rem', + '2xl': '1.5rem', + '3xl': '1.875rem', + '4xl': '2.25rem', + }, + fontWeight: { + normal: 400, + medium: 500, + semibold: 600, + bold: 700, + }, + }, + spacing: { + xs: '0.25rem', + sm: '0.5rem', + md: '1rem', + lg: '1.5rem', + xl: '2rem', + '2xl': '3rem', + }, + borderRadius: { + sm: '0.375rem', + md: '0.5rem', + lg: '0.75rem', + xl: '1rem', + full: '9999px', + }, + shadows: { + sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', + md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)', + lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1)', + xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1)', + }, + transitions: { + default: '0.3s ease', + fast: '0.15s ease', + slow: '0.5s ease', + }, + breakpoints: { + sm: '640px', + md: '768px', + lg: '1024px', + xl: '1280px', + '2xl': '1536px', + }, +}; + +export const GlobalStyle = createGlobalStyle` + :root { + --primary: ${theme.colors.primary}; + --secondary: ${theme.colors.secondary}; + --background: ${theme.colors.background.light}; + --text-primary: ${theme.colors.text.primary}; + --text-secondary: ${theme.colors.text.secondary}; + } + + @media (prefers-color-scheme: dark) { + :root { + --background: ${theme.colors.background.dark}; + --text-primary: ${theme.colors.text.light}; + --text-secondary: ${theme.colors.text.light}; + } + } + + * { + margin: 0; + padding: 0; + box-sizing: border-box; + } + + body { + font-family: ${theme.typography.fontFamily.pc}; + background: var(--background); + color: var(--text-primary); + line-height: 1.5; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + + @media (max-width: ${theme.breakpoints.md}) { + body { + font-family: ${theme.typography.fontFamily.mobile}; + } + } + + button { + font-family: inherit; + } + + /* 滚动条样式 */ + ::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + ::-webkit-scrollbar-track { + background: transparent; + } + + ::-webkit-scrollbar-thumb { + background: ${theme.colors.primary}40; + border-radius: ${theme.borderRadius.full}; + } + + ::-webkit-scrollbar-thumb:hover { + background: ${theme.colors.primary}60; + } +`; \ No newline at end of file diff --git a/server/index.js b/server/index.js index a2475ce6..f4a3bcab 100644 --- a/server/index.js +++ b/server/index.js @@ -30,21 +30,47 @@ async function initDatabase() { try { const connection = await pool.getConnection(); + // 创建用户表 + await connection.execute(` + CREATE TABLE IF NOT EXISTS users ( + id INT AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(64) NOT NULL UNIQUE, + password VARCHAR(255) NOT NULL, + is_admin BOOLEAN DEFAULT FALSE, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + `); + // 创建待办事项表 await connection.execute(` CREATE TABLE IF NOT EXISTS todos ( id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255) NOT NULL, + description TEXT, priority ENUM('low', 'medium', 'high', 'urgent') DEFAULT 'medium', completed BOOLEAN DEFAULT FALSE, suspended BOOLEAN DEFAULT FALSE, date DATE NOT NULL, suspended_date DATE NULL, + user_id INT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) `); + // 添加user_id字段(如果表已存在但没有该字段) + try { + await connection.execute(` + ALTER TABLE todos + ADD COLUMN user_id INT NOT NULL, + ADD CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE + `); + } catch (error) { + // 字段可能已存在,忽略错误 + console.log('User_id column may already exist'); + } + // 添加suspended字段(如果表已存在但没有该字段) try { await connection.execute(` @@ -56,6 +82,30 @@ async function initDatabase() { // 字段可能已存在,忽略错误 console.log('Suspended columns may already exist'); } + + // 添加description字段(如果表已存在但没有该字段) + try { + await connection.execute(` + ALTER TABLE todos + ADD COLUMN description TEXT + `); + } catch (error) { + // 字段可能已存在,忽略错误 + console.log('Description column may already exist'); + } + + // 创建默认管理员用户 + const adminPassword = await bcrypt.hash('weiMonkey2024', 10); + try { + await connection.execute(` + INSERT INTO users (username, password, is_admin) + VALUES ('admin', ?, TRUE) + `, [adminPassword]); + console.log('默认管理员用户创建成功'); + } catch (error) { + // 用户可能已存在 + console.log('默认管理员用户可能已存在'); + } connection.release(); console.log('数据库表初始化成功'); @@ -76,14 +126,6 @@ const authenticatePassword = (req, res, next) => { next(); }; -// 路由 - -// 验证密码 -app.post('/api/auth', authenticatePassword, (req, res) => { - const token = jwt.sign({ authenticated: true }, JWT_SECRET, { expiresIn: '24h' }); - res.json({ success: true, token }); -}); - // 验证token的中间件 const authenticateToken = (req, res, next) => { const authHeader = req.headers['authorization']; @@ -102,6 +144,136 @@ const authenticateToken = (req, res, next) => { }); }; +// 验证管理员权限的中间件 +const authenticateAdmin = (req, res, next) => { + if (!req.user.is_admin) { + return res.status(403).json({ error: '需要管理员权限' }); + } + next(); +}; + +// 路由 + +// 用户登录 +app.post('/api/auth/login', async (req, res) => { + try { + const { username, password } = req.body; + + if (!username || !password) { + return res.status(400).json({ error: '用户名和密码是必需的' }); + } + + const connection = await pool.getConnection(); + + // 查找用户 + const [users] = await connection.execute( + 'SELECT * FROM users WHERE username = ?', + [username] + ); + + connection.release(); + + if (users.length === 0) { + return res.status(401).json({ error: '用户名或密码错误' }); + } + + const user = users[0]; + + // 验证密码 + const isValidPassword = await bcrypt.compare(password, user.password); + if (!isValidPassword) { + return res.status(401).json({ error: '用户名或密码错误' }); + } + + // 生成token + const token = jwt.sign( + { + userId: user.id, + username: user.username, + is_admin: user.is_admin + }, + JWT_SECRET, + { expiresIn: '24h' } + ); + + res.json({ + success: true, + token, + user: { + id: user.id, + username: user.username, + is_admin: user.is_admin + } + }); + } catch (error) { + console.error('登录失败:', error); + res.status(500).json({ error: '服务器错误' }); + } +}); + +// 管理员添加用户 +app.post('/api/auth/register', authenticateToken, authenticateAdmin, async (req, res) => { + try { + const { username, password } = req.body; + + if (!username || !password) { + return res.status(400).json({ error: '用户名和密码是必需的' }); + } + + if (password.length < 6) { + return res.status(400).json({ error: '密码长度至少6位' }); + } + + const connection = await pool.getConnection(); + + // 检查用户名是否已存在 + const [existingUsers] = await connection.execute( + 'SELECT id FROM users WHERE username = ?', + [username] + ); + + if (existingUsers.length > 0) { + connection.release(); + return res.status(400).json({ error: '用户名已存在' }); + } + + // 创建新用户 + const hashedPassword = await bcrypt.hash(password, 10); + const [result] = await connection.execute( + 'INSERT INTO users (username, password, is_admin) VALUES (?, ?, FALSE)', + [username, hashedPassword] + ); + + connection.release(); + + res.json({ + success: true, + message: '用户创建成功', + userId: result.insertId + }); + } catch (error) { + console.error('注册用户失败:', error); + res.status(500).json({ error: '服务器错误' }); + } +}); + +// 获取所有用户(仅管理员) +app.get('/api/users', authenticateToken, authenticateAdmin, async (req, res) => { + try { + const connection = await pool.getConnection(); + + const [users] = await connection.execute( + 'SELECT id, username, is_admin, created_at FROM users ORDER BY created_at DESC' + ); + + connection.release(); + res.json(users); + } catch (error) { + console.error('获取用户列表失败:', error); + res.status(500).json({ error: '服务器错误' }); + } +}); + // 获取历史待办事项(一周之前的) app.get('/api/todos/history', authenticateToken, async (req, res) => { try { @@ -111,10 +283,13 @@ app.get('/api/todos/history', authenticateToken, async (req, res) => { const today = new Date(); const oneWeekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); - const [rows] = await connection.execute( - 'SELECT * FROM todos WHERE date < ? ORDER BY date DESC, priority DESC, created_at DESC', - [oneWeekAgo.toISOString().split('T')[0]] - ); + // 管理员可以查看所有用户的数据,普通用户只能查看自己的 + let query = 'SELECT * FROM todos WHERE date < ? AND user_id = ? ORDER BY date DESC, priority DESC, created_at DESC'; + let params = [oneWeekAgo.toISOString().split('T')[0]]; + params.push(req.user.userId); + + + const [rows] = await connection.execute(query, params); connection.release(); res.json(rows); @@ -133,10 +308,12 @@ app.get('/api/todos', authenticateToken, async (req, res) => { const today = new Date(); const oneWeekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); - const [rows] = await connection.execute( - 'SELECT * FROM todos WHERE date >= ? AND date <= ? AND suspended = FALSE ORDER BY date DESC, priority DESC, created_at DESC', - [oneWeekAgo.toISOString().split('T')[0], today.toISOString().split('T')[0]] - ); + // 管理员可以查看所有用户的数据,普通用户只能查看自己的 + let query = 'SELECT * FROM todos WHERE date >= ? AND date <= ? AND suspended = FALSE AND user_id = ? ORDER BY date DESC, priority DESC, created_at DESC'; + + let params = [oneWeekAgo.toISOString().split('T')[0], today.toISOString().split('T')[0]]; + params.push(req.user.userId); + const [rows] = await connection.execute(query, params); connection.release(); res.json(rows); @@ -149,7 +326,7 @@ app.get('/api/todos', authenticateToken, async (req, res) => { // 创建新的待办事项 app.post('/api/todos', authenticateToken, async (req, res) => { try { - const { title, priority, date } = req.body; + const { title, priority, date, description } = req.body; if (!title || !date) { return res.status(400).json({ error: '标题和日期是必需的' }); @@ -158,8 +335,8 @@ app.post('/api/todos', authenticateToken, async (req, res) => { const connection = await pool.getConnection(); const [result] = await connection.execute( - 'INSERT INTO todos (title, priority, date) VALUES (?, ?, ?)', - [title, priority || 'medium', date] + 'INSERT INTO todos (title, description, priority, date, user_id) VALUES (?, ?, ?, ?, ?)', + [title, description || null, priority || 'medium', date, req.user.userId] ); const [newTodo] = await connection.execute( @@ -179,15 +356,70 @@ app.post('/api/todos', authenticateToken, async (req, res) => { app.put('/api/todos/:id', authenticateToken, async (req, res) => { try { const { id } = req.params; - const { completed } = req.body; + const { completed, title, priority, date, description } = req.body; const connection = await pool.getConnection(); + // 检查待办事项是否存在且属于当前用户(管理员可以修改所有) + let checkQuery = 'SELECT * FROM todos WHERE id = ?'; + let checkParams = [id]; + + if (!req.user.is_admin) { + checkQuery = 'SELECT * FROM todos WHERE id = ? AND user_id = ?'; + checkParams.push(req.user.userId); + } + + const [existingTodos] = await connection.execute(checkQuery, checkParams); + + if (existingTodos.length === 0) { + connection.release(); + return res.status(404).json({ error: '待办事项不存在或无权限访问' }); + } + + // 构建更新字段和值 + const updates = []; + const values = []; + + if (completed !== undefined) { + updates.push('completed = ?'); + values.push(completed); + } + + if (title !== undefined) { + updates.push('title = ?'); + values.push(title); + } + + if (priority !== undefined) { + updates.push('priority = ?'); + values.push(priority); + } + + if (date !== undefined) { + updates.push('date = ?'); + values.push(date); + } + + if (description !== undefined) { + updates.push('description = ?'); + values.push(description || null); + } + + if (updates.length === 0) { + connection.release(); + return res.status(400).json({ error: '没有提供要更新的字段' }); + } + + // 添加 id 到值数组 + values.push(id); + + // 执行更新 await connection.execute( - 'UPDATE todos SET completed = ? WHERE id = ?', - [completed, id] + `UPDATE todos SET ${updates.join(', ')} WHERE id = ?`, + values ); + // 获取更新后的待办事项 const [updatedTodo] = await connection.execute( 'SELECT * FROM todos WHERE id = ?', [id] @@ -208,6 +440,22 @@ app.delete('/api/todos/:id', authenticateToken, async (req, res) => { const connection = await pool.getConnection(); + // 检查待办事项是否存在且属于当前用户(管理员可以删除所有) + let checkQuery = 'SELECT * FROM todos WHERE id = ?'; + let checkParams = [id]; + + if (!req.user.is_admin) { + checkQuery = 'SELECT * FROM todos WHERE id = ? AND user_id = ?'; + checkParams.push(req.user.userId); + } + + const [existingTodos] = await connection.execute(checkQuery, checkParams); + + if (existingTodos.length === 0) { + connection.release(); + return res.status(404).json({ error: '待办事项不存在或无权限访问' }); + } + await connection.execute('DELETE FROM todos WHERE id = ?', [id]); connection.release(); @@ -226,15 +474,17 @@ app.put('/api/todos/:id/suspend', authenticateToken, async (req, res) => { const connection = await pool.getConnection(); - // 检查是否是今天的待办事项 - const [todoCheck] = await connection.execute( - 'SELECT * FROM todos WHERE id = ? AND date = ?', - [id, today] - ); + // 检查是否是今天的待办事项且属于当前用户 + let checkQuery = 'SELECT * FROM todos WHERE id = ? AND date = ? AND user_id = ?'; + let checkParams = [id, today]; + checkParams.push(req.user.userId); + + + const [todoCheck] = await connection.execute(checkQuery, checkParams); if (todoCheck.length === 0) { connection.release(); - return res.status(400).json({ error: '只能挂起今天的待办事项' }); + return res.status(400).json({ error: '只能挂起今天的待办事项或无权限访问' }); } // 更新挂起状态 @@ -261,9 +511,13 @@ app.get('/api/todos/suspended', authenticateToken, async (req, res) => { try { const connection = await pool.getConnection(); - const [rows] = await connection.execute( - 'SELECT * FROM todos WHERE suspended = TRUE ORDER BY suspended_date DESC, priority DESC, created_at DESC' - ); + // 管理员可以查看所有用户的挂起待办,普通用户只能查看自己的 + let query = 'SELECT * FROM todos WHERE suspended = TRUE AND user_id = ? ORDER BY suspended_date DESC, priority DESC, created_at DESC'; + let params = []; + params.push(req.user.userId); + + + const [rows] = await connection.execute(query, params); connection.release(); res.json(rows); @@ -281,15 +535,17 @@ app.put('/api/todos/:id/resume', authenticateToken, async (req, res) => { const connection = await pool.getConnection(); - // 检查是否是挂起的待办事项 - const [todoCheck] = await connection.execute( - 'SELECT * FROM todos WHERE id = ? AND suspended = TRUE', - [id] - ); + // 检查是否是挂起的待办事项且属于当前用户 + let checkQuery = 'SELECT * FROM todos WHERE id = ? AND suspended = TRUE AND user_id = ?'; + let checkParams = [id]; + checkParams.push(req.user.userId); + + + const [todoCheck] = await connection.execute(checkQuery, checkParams); if (todoCheck.length === 0) { connection.release(); - return res.status(400).json({ error: '待办事项未处于挂起状态' }); + return res.status(400).json({ error: '待办事项未处于挂起状态或无权限访问' }); } // 恢复待办事项到今天 @@ -320,10 +576,11 @@ app.post('/api/todos/migrate-pending', authenticateToken, async (req, res) => { const today = new Date().toISOString().split('T')[0]; // 查找今天之前所有未完成且未挂起的待办事项 - const [pendingTodos] = await connection.execute( - 'SELECT * FROM todos WHERE date < ? AND completed = FALSE AND suspended = FALSE ORDER BY date DESC, priority DESC', - [today] - ); + let query = 'SELECT * FROM todos WHERE date < ? AND completed = FALSE AND suspended = FALSE AND user_id = ? ORDER BY date DESC, priority DESC'; + let params = [today]; + params.push(req.user.userId); + + const [pendingTodos] = await connection.execute(query, params); let migratedCount = 0;