Pārlūkot izejas kodu

add route prefix

周玉环 2 nedēļas atpakaļ
vecāks
revīzija
a5b3897be1

+ 10 - 139
src/pages/content-model/index.module.css

@@ -1,160 +1,42 @@
 /* 内容模型页面样式 */
 
 .page {
-  padding: 32px 40px;
   background-color: #fff;
   min-height: 100%;
 }
 
-/* 页面头部 */
-.pageHeader {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 24px;
-}
-
-.pageHeaderLeft {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-}
-
-.pageTitle {
-  font-size: 28px;
-  font-weight: 400;
-  color: #1a1a1a;
-  margin: 0;
-}
-
-.helpIcon {
-  display: inline-flex;
-  align-items: center;
-  justify-content: center;
-  width: 20px;
-  height: 20px;
-  border-radius: 50%;
-  border: 1px solid #ccc;
-  font-size: 12px;
-  color: #666;
-  cursor: help;
-}
-
-.pageHeaderRight {
-  display: flex;
-  gap: 12px;
-}
-
-/* 搜索栏 */
-.searchBar {
-  margin-bottom: 24px;
-}
-
-.searchBar input {
-  max-width: 500px;
+/* 搜索输入框 */
+.searchInput {
+  width: 70%;
 }
 
 /* 表格容器 */
 .tableContainer {
   background: white;
   border: 1px solid #e5e8eb;
-  border-radius: 4px;
+  border-radius: 6px;
   overflow: hidden;
 }
 
-.loadingContainer {
-  display: flex;
-  justify-content: center;
-  align-items: center;
-  padding: 60px;
-}
-
-/* 表格样式 */
-.table {
-  width: 100%;
-  border-collapse: collapse;
-  font-size: 14px;
-}
-
-.table thead {
+/* 表格行悬停效果 */
+.tableRow:hover {
   background-color: #f7f9fa;
-  border-bottom: 1px solid #e5e8eb;
-}
-
-.table th {
-  text-align: left;
-  padding: 12px 16px;
-  font-weight: 500;
-  color: #666;
-  font-size: 13px;
 }
 
+/* 表头样式 */
 .thName {
   width: 35%;
 }
 
-.thFields {
-  width: 15%;
-}
-
-.thUpdatedBy {
-  width: 25%;
-}
-
-.thUpdated {
-  width: 25%;
-}
-
+/* 排序图标 */
 .sortIcon {
   margin-left: 4px;
   color: #999;
   font-size: 12px;
+  cursor: pointer;
 }
 
-.table tbody tr {
-  border-bottom: 1px solid #f0f0f0;
-  transition: background-color 0.15s;
-}
-
-.table tbody tr:hover {
-  background-color: #f7f9fa;
-}
-
-.table tbody tr:last-child {
-  border-bottom: none;
-}
-
-.table td {
-  padding: 16px;
-  color: #333;
-}
-
-.tdName {
-  font-weight: 500;
-}
-
-.modelName {
-  font-size: 14px;
-  color: #1a1a1a;
-  margin-bottom: 4px;
-}
-
-.modelId {
-  font-size: 12px;
-  color: #999;
-  font-weight: 400;
-}
-
-.tdFields {
-  color: #666;
-}
-
-.userInfo {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-}
-
+/* 用户头像 */
 .avatar {
   width: 24px;
   height: 24px;
@@ -165,14 +47,3 @@
   justify-content: center;
   font-size: 12px;
 }
-
-.tdUpdated {
-  color: #666;
-  font-size: 13px;
-}
-
-.emptyState {
-  text-align: center;
-  padding: 60px 20px;
-  color: #999;
-}

+ 111 - 69
src/pages/content-model/index.tsx

@@ -1,6 +1,20 @@
 import { useState, useEffect } from "react";
-import { Button, TextInput, Spinner } from "@contentful/f36-components";
-import { contentModelApi, type ContentModel } from "../../services/modules/contentModel";
+import {
+  Button,
+  TextInput,
+  Spinner,
+  Flex,
+  Box,
+  Heading,
+  Text,
+  Table,
+  IconButton,
+} from "@contentful/f36-components";
+import { QuestionIcon } from "@contentful/f36-icons";
+import {
+  contentModelApi,
+  type ContentModel,
+} from "../../services/modules/contentModel";
 import styles from "./index.module.css";
 
 export default function ContentModelPage() {
@@ -40,89 +54,117 @@ export default function ContentModelPage() {
   };
 
   return (
-    <div className={styles.page}>
-      {/* 页面头部 */}
-      <div className={styles.pageHeader}>
-        <div className={styles.pageHeaderLeft}>
-          <h1 className={styles.pageTitle}>Content model</h1>
-          <span className={styles.helpIcon}>?</span>
-        </div>
-        <div className={styles.pageHeaderRight}>
+    <Box padding="spacingXl" className={styles.page}>
+      {/* 页面头部 - 标题、搜索框、按钮在同一行 */}
+      <Flex
+        alignItems="center"
+        justifyContent="center"
+        gap="spacingM"
+        marginBottom="spacingL"
+      >
+        {/* 标题和帮助图标 */}
+        <Flex alignItems="center" gap="spacingXs" style={{ flexShrink: 0 }}>
+          <Heading as="h1" marginBottom="none">
+            Content model
+          </Heading>
+          <IconButton
+            variant="transparent"
+            size="small"
+            icon={<QuestionIcon />}
+            aria-label="帮助"
+          />
+        </Flex>
+
+        {/* 搜索框 - 自适应剩余空间 */}
+        <Box style={{ flex: 1, display: 'flex', justifyContent: 'center' }}>
+          <TextInput
+            placeholder="Search for a content type"
+            value={searchText}
+            size='small'
+            onChange={(e) => handleSearch(e.target.value)}
+            className={styles.searchInput}
+          />
+        </Box>
+
+        {/* 右侧按钮 */}
+        <Flex gap="spacingS" style={{ flexShrink: 0 }}>
           <Button variant="secondary" size="small">
             Visual Modeler
           </Button>
           <Button variant="primary" size="small" onClick={handleCreate}>
             + Create content type
           </Button>
-        </div>
-      </div>
-
-      {/* 搜索栏 */}
-      <div className={styles.searchBar}>
-        <TextInput
-          placeholder="Search for a content type"
-          value={searchText}
-          onChange={(e) => handleSearch(e.target.value)}
-        />
-      </div>
+        </Flex>
+      </Flex>
 
       {/* 表格 */}
-      <div className={styles.tableContainer}>
+      <Box className={styles.tableContainer}>
         {loading ? (
-          <div className={styles.loadingContainer}>
+          <Flex justifyContent="center" alignItems="center" padding="spacingXl">
             <Spinner />
-          </div>
+          </Flex>
         ) : (
-          <table className={styles.table}>
-            <thead>
-              <tr>
-                <th className={styles.thName}>
-                  Name <span className={styles.sortIcon}>⇅</span>
-                </th>
-                <th className={styles.thFields}>Fields</th>
-                <th className={styles.thUpdatedBy}>Last Updated By</th>
-                <th className={styles.thUpdated}>Updated</th>
-              </tr>
-            </thead>
-            <tbody>
+          <Table>
+            <Table.Head>
+              <Table.Row>
+                <Table.Cell className={styles.thName}>
+                  <Flex alignItems="center" gap="spacingXs">
+                    <Text>Name</Text>
+                    <span className={styles.sortIcon}>⇅</span>
+                  </Flex>
+                </Table.Cell>
+                <Table.Cell>Fields</Table.Cell>
+                <Table.Cell>Last Updated By</Table.Cell>
+                <Table.Cell>Updated</Table.Cell>
+              </Table.Row>
+            </Table.Head>
+            <Table.Body>
               {models.length > 0 ? (
                 models.map((model) => (
-                  <tr key={model.id} className={styles.tableRow}>
-                    <td className={styles.tdName}>
-                      <div className={styles.modelName}>{model.name}</div>
-                      <div className={styles.modelId}>{model.id}</div>
-                    </td>
-                    <td className={styles.tdFields}>
-                      {model.fields?.length || 0}
-                    </td>
-                    <td className={styles.tdUpdatedBy}>
-                      <div className={styles.userInfo}>
-                        <span className={styles.avatar}>👤</span>
-                        <span>管理员</span>
-                      </div>
-                    </td>
-                    <td className={styles.tdUpdated}>
-                      {new Date(model.updatedAt).toLocaleString("zh-CN", {
-                        year: "numeric",
-                        month: "2-digit",
-                        day: "2-digit",
-                        hour: "2-digit",
-                        minute: "2-digit",
-                      })}
-                    </td>
-                  </tr>
+                  <Table.Row key={model.id} className={styles.tableRow}>
+                    <Table.Cell>
+                      <Box>
+                        <Text fontWeight="fontWeightMedium">{model.name}</Text>
+                        <Text fontSize="fontSizeS" fontColor="gray500">
+                          {model.id}
+                        </Text>
+                      </Box>
+                    </Table.Cell>
+                    <Table.Cell>
+                      <Text>{model.fields?.length || 0}</Text>
+                    </Table.Cell>
+                    <Table.Cell>
+                      <Flex alignItems="center" gap="spacingXs">
+                        <Box className={styles.avatar}>👤</Box>
+                        <Text>管理员</Text>
+                      </Flex>
+                    </Table.Cell>
+                    <Table.Cell>
+                      <Text fontSize="fontSizeS" fontColor="gray600">
+                        {new Date(model.updatedAt).toLocaleString("zh-CN", {
+                          year: "numeric",
+                          month: "2-digit",
+                          day: "2-digit",
+                          hour: "2-digit",
+                          minute: "2-digit",
+                        })}
+                      </Text>
+                    </Table.Cell>
+                  </Table.Row>
                 ))
               ) : (
-                <tr>
-                  <td colSpan={4} className={styles.emptyState}>
-                    暂无数据
-                  </td>
-                </tr>
+                <Table.Row>
+                  <Table.Cell colSpan={4}>
+                    <Flex justifyContent="center" padding="spacingXl">
+                      <Text fontColor="gray500">暂无数据</Text>
+                    </Flex>
+                  </Table.Cell>
+                </Table.Row>
               )}
-            </tbody>
-          </table>
+            </Table.Body>
+          </Table>
         )}
-      </div>
-    </div>
+      </Box>
+    </Box>
   );
 }

+ 4 - 1
src/router/index.tsx

@@ -194,5 +194,8 @@ export function createAppRouter(menus: JeecgMenu[]) {
     }
   });
   
-  return createBrowserRouter(routes);
+  // 创建路由器,不使用 basename(因为 Navbar 会添加 /spaces)
+  return createBrowserRouter(routes, {
+    basename: "/spaces",
+  });
 }

+ 1 - 0
vite.config.ts

@@ -6,6 +6,7 @@ export default defineConfig(() => {
   // 加载环境变量
   return {
     plugins: [react()],
+    base: '/spaces/',   // ← 必须加这一行
 
     // 路径别名
     resolve: {