diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..22f58ad1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[.gitconfig] +indent_style = tab + +[Makefile] +indent_style = tab + +[*.md] +trim_trailing_whitespace = false diff --git a/shared/model/user.ts b/shared/model/user.ts index a618c5fc..08223eaa 100644 --- a/shared/model/user.ts +++ b/shared/model/user.ts @@ -1,12 +1,14 @@ import { request } from '../api/request'; -export interface UserLoginInfo { +export interface UserBaseInfo { _id: string; email: string; nickname: string; - password: string; - token: string; avatar: string | null; +} + +export interface UserLoginInfo extends UserBaseInfo { + token: string; createdAt: string; } diff --git a/shared/redux/slices/user.ts b/shared/redux/slices/user.ts index ec301bf0..3b3a8469 100644 --- a/shared/redux/slices/user.ts +++ b/shared/redux/slices/user.ts @@ -1,11 +1,12 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import type { UserLoginInfo } from '../../model/user'; +import type { UserBaseInfo, UserLoginInfo } from '../../model/user'; interface UserState { info: UserLoginInfo | null; + friends: UserBaseInfo[]; } -const initialState: UserState = { info: null }; +const initialState: UserState = { info: null, friends: [] }; const userSlice = createSlice({ name: 'user', diff --git a/web/src/components/PillTabs.less b/web/src/components/PillTabs.less new file mode 100644 index 00000000..1d8d121d --- /dev/null +++ b/web/src/components/PillTabs.less @@ -0,0 +1,34 @@ +.pill-tabs.ant-tabs.ant-tabs-card { + // color: ${(props) => props.theme.color.textNormal}; + @apply text-gray-100; + + .ant-tabs-nav { + @apply px-2 py-3 m-0 text-base; + + &::before { + @apply border-0; + } + + .ant-tabs-tab { + border: 0; + margin: 2px; + padding: 2px 8px; + @apply text-gray-200 bg-opacity-0 bg-white; + + &.ant-tabs-tab-active, + &:hover, + &:active { + @apply rounded bg-opacity-20; + + .ant-tabs-tab-btn { + @apply text-white; + } + } + } + } + + .ant-tabs-content-holder { + overflow-x: hidden; + overflow-y: auto; + } +} diff --git a/web/src/components/PillTabs.tsx b/web/src/components/PillTabs.tsx new file mode 100644 index 00000000..03bbb146 --- /dev/null +++ b/web/src/components/PillTabs.tsx @@ -0,0 +1,15 @@ +import { Tabs } from 'antd'; +import React from 'react'; + +import './PillTabs.less'; + +export const PillTabs = React.memo((props) => { + return ( + + {props.children} + + ); +}); +PillTabs.displayName = 'PillTabs'; + +export const PillTabPane = Tabs.TabPane; diff --git a/web/src/routes/Main/Content.tsx b/web/src/routes/Main/Content.tsx new file mode 100644 index 00000000..93af1ddc --- /dev/null +++ b/web/src/routes/Main/Content.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { PillTabs, PillTabPane } from '../../components/PillTabs'; +import { useAppSelector } from '../../hooks/useAppSelector'; + +/** + * 主要内容组件 + */ +export const Content: React.FC = React.memo(() => { + const friends = useAppSelector((state) => state.user.friends); + + return ( +
+ + +
+
好友列表
+
{JSON.stringify(friends)}
+
+
+
+
+ ); +}); +Content.displayName = 'Content'; diff --git a/web/src/routes/Main/index.tsx b/web/src/routes/Main/index.tsx index 6ce197e6..9bdf7bb2 100644 --- a/web/src/routes/Main/index.tsx +++ b/web/src/routes/Main/index.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Content } from './Content'; import { Navbar } from './Navbar'; import { MainProvider } from './Provider'; import { Sidebar } from './Sidebar'; @@ -11,7 +12,7 @@ export const MainRoute: React.FC = React.memo(() => { -
{/* Main Content */}
+ );