Kaynağa Gözat

AI: 教会会友信息管理与考勤打卡系统

D8D AI 1 yıl önce
ebeveyn
işleme
d2c4be87b5

+ 34 - 6
src/App.tsx

@@ -1,11 +1,39 @@
-import React from 'react'
+import React from 'react';
+import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
+import { ThemeProvider } from './contexts/ThemeContext';
+import Header from './components/Header';
+import Footer from './components/Footer';
+import Dashboard from './pages/Dashboard';
+import MemberList from './pages/MemberList';
+import AttendanceManagement from './pages/AttendanceManagement';
+import Login from './pages/Login';
 
 function App() {
   return (
-    <div className="min-h-screen bg-gray-100 flex items-center justify-center">
-      <p>Start prompting (or editing) to see magic happen :)</p>
-    </div>
-  )
+    <ThemeProvider>
+      <Router>
+        <div className="flex flex-col min-h-screen bg-gray-100 dark:bg-gray-900">
+          <Header />
+          <nav className="bg-white dark:bg-gray-800 shadow-md">
+            <ul className="flex justify-center space-x-4 p-4">
+              <li><Link to="/" className="text-blue-600 dark:text-blue-400 hover:underline">首页</Link></li>
+              <li><Link to="/members" className="text-blue-600 dark:text-blue-400 hover:underline">会友管理</Link></li>
+              <li><Link to="/attendance" className="text-blue-600 dark:text-blue-400 hover:underline">考勤管理</Link></li>
+            </ul>
+          </nav>
+          <main className="flex-grow container mx-auto px-4 py-8">
+            <Routes>
+              <Route path="/" element={<Dashboard />} />
+              <Route path="/members" element={<MemberList />} />
+              <Route path="/attendance" element={<AttendanceManagement />} />
+              <Route path="/login" element={<Login />} />
+            </Routes>
+          </main>
+          <Footer />
+        </div>
+      </Router>
+    </ThemeProvider>
+  );
 }
 
-export default App
+export default App;

+ 13 - 0
src/components/Footer.tsx

@@ -0,0 +1,13 @@
+import React from 'react';
+
+const Footer: React.FC = () => {
+  return (
+    <footer className="bg-white dark:bg-gray-800 shadow-md mt-8">
+      <div className="container mx-auto px-4 py-6 text-center text-gray-600 dark:text-gray-400">
+        © {new Date().getFullYear()} 教会管理系统. 保留所有权利。
+      </div>
+    </footer>
+  );
+};
+
+export default Footer;

+ 24 - 0
src/components/Header.tsx

@@ -0,0 +1,24 @@
+import React from 'react';
+import { useTheme } from '../contexts/ThemeContext';
+import { Moon, Sun } from 'lucide-react';
+
+const Header: React.FC = () => {
+  const { theme, toggleTheme } = useTheme();
+
+  return (
+    <header className="bg-white dark:bg-gray-800 shadow-md">
+      <div className="container mx-auto px-4 py-6 flex justify-between items-center">
+        <h1 className="text-2xl font-bold text-gray-800 dark:text-white">教会管理系统</h1>
+        <button
+          onClick={toggleTheme}
+          className="p-2 rounded-full bg-gray-200 dark:bg-gray-700"
+          aria-label="Toggle theme"
+        >
+          {theme === 'light' ? <Moon size={20} /> : <Sun size={20} />}
+        </button>
+      </div>
+    </header>
+  );
+};
+
+export default Header;

+ 44 - 0
src/contexts/ThemeContext.tsx

@@ -0,0 +1,44 @@
+import React, { createContext, useState, useContext, useEffect } from 'react';
+
+type Theme = 'light' | 'dark';
+
+interface ThemeContextType {
+  theme: Theme;
+  toggleTheme: () => void;
+}
+
+const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
+
+export const useTheme = () => {
+  const context = useContext(ThemeContext);
+  if (context === undefined) {
+    throw new Error('useTheme must be used within a ThemeProvider');
+  }
+  return context;
+};
+
+export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
+  const [theme, setTheme] = useState<Theme>('light');
+
+  useEffect(() => {
+    const savedTheme = localStorage.getItem('theme') as Theme | null;
+    if (savedTheme) {
+      setTheme(savedTheme);
+    }
+  }, []);
+
+  useEffect(() => {
+    document.documentElement.classList.toggle('dark', theme === 'dark');
+    localStorage.setItem('theme', theme);
+  }, [theme]);
+
+  const toggleTheme = () => {
+    setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');
+  };
+
+  return (
+    <ThemeContext.Provider value={{ theme, toggleTheme }}>
+      {children}
+    </ThemeContext.Provider>
+  );
+};

+ 13 - 0
src/pages/Dashboard.tsx

@@ -0,0 +1,13 @@
+import React from 'react';
+
+const Dashboard: React.FC = () => {
+  return (
+    <div className="bg-white dark:bg-gray-800 shadow rounded-lg p-6">
+      <h2 className="text-2xl font-semibold text-gray-800 dark:text-white mb-4">仪表板</h2>
+      <p className="text-gray-600 dark:text-gray-300">欢迎使用教会管理系统。在这里您可以查看概览信息和快速访问各项功能。</p>
+      {/* 这里可以添加一些统计数据或快速链接 */}
+    </div>
+  );
+};
+
+export default Dashboard;