├── bitbit ├── src │ ├── pages │ │ ├── Settings.tsx │ │ ├── ProfileSettings.tsx │ │ ├── ChatTestPage.tsx │ │ ├── FollowListPage.tsx │ │ ├── Login.tsx │ │ ├── Register.tsx │ │ ├── Community.tsx │ │ └── NotificationsNew.tsx │ ├── shared │ │ ├── hooks │ │ │ ├── useToast.ts │ │ │ ├── index.ts │ │ │ ├── useMediaQuery.ts │ │ │ ├── useChatNavigation.ts │ │ │ └── usePublishStatus.ts │ │ ├── services │ │ │ ├── index.ts │ │ │ └── api.ts │ │ ├── constants │ │ │ └── index.ts │ │ ├── config │ │ │ ├── index.ts │ │ │ └── constants.ts │ │ ├── utils │ │ │ ├── index.ts │ │ │ ├── cn.ts │ │ │ ├── date.ts │ │ │ ├── validation.ts │ │ │ └── scrollUtils.ts │ │ ├── index.ts │ │ ├── components │ │ │ ├── index.ts │ │ │ ├── SortSelector │ │ │ │ └── index.tsx │ │ │ ├── TabFilter │ │ │ │ └── index.tsx │ │ │ ├── SearchBar │ │ │ │ └── index.tsx │ │ │ └── SimpleSearchFilter │ │ │ │ └── index.tsx │ │ └── types │ │ │ └── index.ts │ ├── components │ │ ├── ui │ │ │ ├── Toast │ │ │ │ └── index.tsx │ │ │ ├── ContentFilter │ │ │ │ ├── FilterControls.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── exports.ts │ │ │ │ └── types.ts │ │ │ ├── FormInput │ │ │ │ ├── index.ts │ │ │ │ └── FormInput.tsx │ │ │ ├── InterestTags │ │ │ │ ├── index.ts │ │ │ │ └── InterestTags.tsx │ │ │ ├── LoadingButton │ │ │ │ ├── index.ts │ │ │ │ └── LoadingButton.tsx │ │ │ ├── GradientBackground │ │ │ │ ├── index.ts │ │ │ │ └── GradientBackground.tsx │ │ │ ├── ItemPreview │ │ │ │ └── index.ts │ │ │ ├── VerificationCodeInput │ │ │ │ ├── index.ts │ │ │ │ └── VerificationCodeInput.tsx │ │ │ ├── PublishStatusModal │ │ │ │ ├── index.ts │ │ │ │ └── PublishStatusModal.tsx │ │ │ ├── Switch │ │ │ │ ├── index.ts │ │ │ │ └── Switch.tsx │ │ │ ├── ThemeToggleButton.tsx │ │ │ ├── cards │ │ │ │ ├── index.ts │ │ │ │ ├── ActivityCard │ │ │ │ │ ├── README.md │ │ │ │ │ ├── types.ts │ │ │ │ │ └── constants.ts │ │ │ │ ├── PostCard │ │ │ │ │ └── types.ts │ │ │ │ └── UserCard │ │ │ │ │ └── types.ts │ │ │ ├── SectionHeader │ │ │ │ └── index.tsx │ │ │ ├── SearchBar │ │ │ │ └── index.tsx │ │ │ ├── EmptyState │ │ │ │ └── index.tsx │ │ │ ├── Container │ │ │ │ └── index.tsx │ │ │ ├── Grid │ │ │ │ └── index.tsx │ │ │ ├── Spinner │ │ │ │ └── index.tsx │ │ │ ├── BaseCard │ │ │ │ ├── types.ts │ │ │ │ ├── variants.ts │ │ │ │ └── index.tsx │ │ │ ├── CategoryItem │ │ │ │ └── index.tsx │ │ │ ├── Breadcrumb │ │ │ │ └── index.tsx │ │ │ ├── Stack │ │ │ │ └── index.tsx │ │ │ ├── PageHeader │ │ │ │ └── index.tsx │ │ │ ├── Toast.tsx │ │ │ └── Tag │ │ │ │ └── index.tsx │ │ ├── layout │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── navigation │ │ │ └── index.ts │ │ ├── common │ │ │ ├── PublishStatus │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ └── index.ts │ │ └── debug │ │ │ └── DebugInfo.tsx │ ├── features │ │ ├── activities │ │ │ ├── hooks │ │ │ │ └── index.ts │ │ │ ├── services │ │ │ │ └── index.ts │ │ │ ├── types │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ └── components │ │ │ │ ├── index.ts │ │ │ │ ├── ActivityForm │ │ │ │ ├── index.ts │ │ │ │ ├── FormActions.tsx │ │ │ │ ├── CategorySection.tsx │ │ │ │ ├── DescriptionSection.tsx │ │ │ │ ├── BasicInfoSection.tsx │ │ │ │ └── ImageUploadSection.tsx │ │ │ │ └── ActivityDetail │ │ │ │ ├── index.ts │ │ │ │ ├── OrganizerInfo.tsx │ │ │ │ ├── ActivityLocation.tsx │ │ │ │ ├── ActivityHeader.tsx │ │ │ │ └── ActivityContent.tsx │ │ ├── auth │ │ │ ├── components │ │ │ │ ├── LoginForm │ │ │ │ │ └── index.ts │ │ │ │ ├── AuthHeader │ │ │ │ │ ├── index.ts │ │ │ │ │ └── AuthHeader.tsx │ │ │ │ ├── RegisterForm │ │ │ │ │ └── index.ts │ │ │ │ ├── UserAvatar │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── services │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── hooks │ │ │ │ ├── index.ts │ │ │ │ └── useVerificationCode.ts │ │ │ └── types │ │ │ │ ├── index.ts │ │ │ │ └── auth.types.ts │ │ ├── exchange │ │ │ ├── hooks │ │ │ │ ├── hooks.ts │ │ │ │ └── index.ts │ │ │ ├── components │ │ │ │ ├── ExchangeCard │ │ │ │ │ └── index.tsx │ │ │ │ ├── PublishSteps │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ └── OrderDetail │ │ │ │ │ ├── index.ts │ │ │ │ │ └── OrderActions.tsx │ │ │ ├── types │ │ │ │ └── index.ts │ │ │ ├── temp-exports.ts │ │ │ └── index.ts │ │ ├── profile │ │ │ ├── components │ │ │ │ ├── Settings │ │ │ │ │ ├── SettingsLayout │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── SettingItem │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── SettingSwitch.tsx │ │ │ │ │ │ ├── SettingSelect.tsx │ │ │ │ │ │ ├── SettingItem.tsx │ │ │ │ │ │ └── SettingNavigation.tsx │ │ │ │ │ ├── modules │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── modals │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── SettingsNavigation.tsx │ │ │ │ ├── ProfileEdit │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── ActivityFilter │ │ │ │ │ └── index.tsx │ │ │ │ ├── OtherUserActivityFilter │ │ │ │ │ └── index.tsx │ │ │ │ └── ProfileTabs │ │ │ │ │ └── index.tsx │ │ │ ├── index.ts │ │ │ ├── utils │ │ │ │ └── index.ts │ │ │ └── hooks │ │ │ │ ├── useSettingsNavigation.ts │ │ │ │ ├── useProfileNavigation.ts │ │ │ │ └── usePagination.ts │ │ ├── chat │ │ │ ├── hooks │ │ │ │ └── index.ts │ │ │ ├── mock │ │ │ │ └── index.ts │ │ │ ├── services │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── utils │ │ │ │ └── index.ts │ │ │ └── components │ │ │ │ ├── index.ts │ │ │ │ ├── ChatPageHeader.tsx │ │ │ │ ├── ConversationListHeader.tsx │ │ │ │ ├── UnreadMessagesBadge.tsx │ │ │ │ └── GroupDismissedNotice.tsx │ │ ├── community │ │ │ ├── index.ts │ │ │ ├── services │ │ │ │ └── index.ts │ │ │ ├── types │ │ │ │ └── index.ts │ │ │ ├── hooks │ │ │ │ └── index.ts │ │ │ └── components │ │ │ │ ├── PostDetail │ │ │ │ ├── index.ts │ │ │ │ ├── PostDetailRecommendations.tsx │ │ │ │ └── PostDetailHeader.tsx │ │ │ │ ├── CommunityHeader │ │ │ │ └── index.tsx │ │ │ │ ├── index.ts │ │ │ │ └── CategorySidebar │ │ │ │ └── index.tsx │ │ └── notifications │ │ │ ├── index.ts │ │ │ ├── components │ │ │ ├── index.ts │ │ │ ├── NotificationTabs.tsx │ │ │ └── NotificationList.tsx │ │ │ └── types │ │ │ └── index.ts │ ├── vite-env.d.ts │ ├── main.tsx │ ├── config │ │ ├── branch.config.ts │ │ ├── dev.config.ts │ │ └── navigation.config.ts │ ├── store │ │ ├── index.ts │ │ └── slices │ │ │ ├── uiSlice.ts │ │ │ ├── userSlice.ts │ │ │ └── settingsSlice.ts │ ├── App.css │ ├── types │ │ ├── index.ts │ │ └── chat.ts │ └── utils │ │ └── testActivityStatusFix.ts ├── .env.development ├── .env.production ├── postcss.config.js ├── tsconfig.json ├── .env.example ├── vercel.json ├── index.html ├── eslint.config.js ├── vite.config.ts ├── tsconfig.node.json ├── .gitignore ├── tsconfig.app.json ├── public │ └── vite.svg ├── package.json ├── README.md ├── tailwind.config.cjs └── tailwind.config.js └── .DS_Store /bitbit/src/pages/Settings.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bitbit/src/shared/hooks/useToast.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/Toast/index.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/hooks/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/services/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/types/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/ContentFilter/FilterControls.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bitbit/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/FormInput/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./FormInput"; 2 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guangmingpeng/BitBit-social-platform/HEAD/.DS_Store -------------------------------------------------------------------------------- /bitbit/src/components/ui/InterestTags/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./InterestTags"; 2 | -------------------------------------------------------------------------------- /bitbit/src/shared/services/index.ts: -------------------------------------------------------------------------------- 1 | // 服务层导出 2 | export { default as api } from "./api"; 3 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/ContentFilter/index.ts: -------------------------------------------------------------------------------- 1 | // 统一导出所有模块 2 | export * from "./exports"; 3 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/LoadingButton/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./LoadingButton"; 2 | -------------------------------------------------------------------------------- /bitbit/src/features/auth/components/LoginForm/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./LoginForm"; 2 | -------------------------------------------------------------------------------- /bitbit/src/features/auth/components/AuthHeader/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./AuthHeader"; 2 | -------------------------------------------------------------------------------- /bitbit/src/features/auth/components/RegisterForm/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./RegisterForm"; 2 | -------------------------------------------------------------------------------- /bitbit/src/features/auth/components/UserAvatar/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./UserAvatar"; 2 | -------------------------------------------------------------------------------- /bitbit/src/features/exchange/hooks/hooks.ts: -------------------------------------------------------------------------------- 1 | // hooks/index.ts 导出文件 2 | export * from "./index"; 3 | -------------------------------------------------------------------------------- /bitbit/src/features/exchange/hooks/index.ts: -------------------------------------------------------------------------------- 1 | // exchange hooks 导出 2 | export * from "./useExchange"; 3 | -------------------------------------------------------------------------------- /bitbit/src/components/layout/index.ts: -------------------------------------------------------------------------------- 1 | // Layout组件导出 2 | export { default as Header } from "./Header"; 3 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/GradientBackground/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./GradientBackground"; 2 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/ItemPreview/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ItemPreview } from "./ItemPreview"; 2 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/VerificationCodeInput/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from "./VerificationCodeInput"; 2 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/PublishStatusModal/index.ts: -------------------------------------------------------------------------------- 1 | export { default as PublishStatusModal } from "./PublishStatusModal"; 2 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/components/Settings/SettingsLayout/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Settings } from "./Settings"; 2 | -------------------------------------------------------------------------------- /bitbit/.env.development: -------------------------------------------------------------------------------- 1 | # Development environment 2 | # Show debug components in development 3 | VITE_SHOW_DEBUG_COMPONENTS=true 4 | -------------------------------------------------------------------------------- /bitbit/.env.production: -------------------------------------------------------------------------------- 1 | # Production environment 2 | # Hide debug components in production 3 | VITE_SHOW_DEBUG_COMPONENTS=false 4 | -------------------------------------------------------------------------------- /bitbit/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /bitbit/src/components/index.ts: -------------------------------------------------------------------------------- 1 | // 导出所有通用组件 2 | export * from './ui' 3 | export * from './layout' 4 | export * from './common' 5 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/Switch/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Switch } from "./Switch"; 2 | export type { SwitchProps } from "./Switch"; 3 | -------------------------------------------------------------------------------- /bitbit/src/shared/constants/index.ts: -------------------------------------------------------------------------------- 1 | // 常量定义 - 当前为空,可在此处添加全局常量 2 | // export const SOME_CONSTANT = 'value'; 3 | 4 | // 导出空对象以避免编译错误 5 | export {}; 6 | -------------------------------------------------------------------------------- /bitbit/src/components/navigation/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SmartBottomNav } from "./SmartBottomNav"; 2 | export { default as FloatingNav } from "./FloatingNav"; 3 | -------------------------------------------------------------------------------- /bitbit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /bitbit/src/components/common/PublishStatus/index.ts: -------------------------------------------------------------------------------- 1 | export { default as PublishStatus } from "./PublishStatus"; 2 | export type { PublishStatusProps } from "./types"; 3 | -------------------------------------------------------------------------------- /bitbit/src/features/auth/services/index.ts: -------------------------------------------------------------------------------- 1 | // 认证相关服务 - 当前为空,可在此处添加认证API服务 2 | // export { authService } from './authService'; 3 | 4 | // 导出空对象以避免编译错误 5 | export {}; 6 | -------------------------------------------------------------------------------- /bitbit/src/features/chat/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export { useChatState } from "./useChatState"; 2 | export type { UseChatStateOptions, UseChatStateReturn } from "./useChatState"; 3 | -------------------------------------------------------------------------------- /bitbit/src/shared/config/index.ts: -------------------------------------------------------------------------------- 1 | // 配置文件导出 2 | export * from "./constants"; 3 | export * from "./routes"; 4 | export * from "./theme"; 5 | export * from "./themeUtils"; 6 | -------------------------------------------------------------------------------- /bitbit/src/features/auth/index.ts: -------------------------------------------------------------------------------- 1 | // auth 功能模块导出 2 | export * from "./components"; 3 | export * from "./hooks"; 4 | export * from "./types"; 5 | export * from "./services"; 6 | -------------------------------------------------------------------------------- /bitbit/src/shared/utils/index.ts: -------------------------------------------------------------------------------- 1 | // 导出所有通用工具函数 2 | export * from "./cn"; 3 | export * from "./date"; 4 | export * from "./validation"; 5 | export * from "./activityUtils"; 6 | -------------------------------------------------------------------------------- /bitbit/src/features/community/index.ts: -------------------------------------------------------------------------------- 1 | // community 功能模块导出 2 | export * from './components' 3 | export * from './hooks' 4 | export * from './types' 5 | export * from './services' 6 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/index.ts: -------------------------------------------------------------------------------- 1 | // activities 功能模块导出 2 | export * from './components' 3 | export * from './hooks' 4 | export * from './types' 5 | export * from './services' 6 | -------------------------------------------------------------------------------- /bitbit/src/features/community/services/index.ts: -------------------------------------------------------------------------------- 1 | // 社区相关服务 - 当前为空,可在此处添加社区API服务 2 | // export { communityService } from './communityService'; 3 | 4 | // 导出空对象以避免编译错误 5 | export {}; 6 | -------------------------------------------------------------------------------- /bitbit/src/features/exchange/components/ExchangeCard/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as ExchangeCard } from "./ExchangeCard"; 2 | export type { ExchangeCardProps } from "./ExchangeCard"; 3 | -------------------------------------------------------------------------------- /bitbit/src/features/chat/mock/index.ts: -------------------------------------------------------------------------------- 1 | // 统一导出所有mock数据 2 | export { mockUsers } from "./users"; 3 | export { mockMessages } from "./messages"; 4 | export { mockConversations } from "./conversations"; 5 | -------------------------------------------------------------------------------- /bitbit/src/features/auth/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export { useAuth } from "./useAuth"; 2 | export { useVerificationCode } from "./useVerificationCode"; 3 | export { useLoginForm, useRegisterForm } from "./useForm"; 4 | -------------------------------------------------------------------------------- /bitbit/src/shared/index.ts: -------------------------------------------------------------------------------- 1 | // 导出所有共享资源 2 | export * from './hooks' 3 | export * from './utils' 4 | export * from './types' 5 | export * from './constants' 6 | export * from './services' 7 | export * from './config' 8 | -------------------------------------------------------------------------------- /bitbit/src/features/auth/types/index.ts: -------------------------------------------------------------------------------- 1 | // 认证相关类型定义 - 当前为空,可在此处添加类型 2 | // export interface User { 3 | // id: string; 4 | // username: string; 5 | // email: string; 6 | // } 7 | 8 | // 导出空对象以避免编译错误 9 | export {}; 10 | -------------------------------------------------------------------------------- /bitbit/src/features/notifications/index.ts: -------------------------------------------------------------------------------- 1 | // 组件 2 | export * from "./components"; 3 | 4 | // Hooks 5 | export * from "./hooks"; 6 | 7 | // 类型 8 | export * from "./types"; 9 | 10 | // 服务 11 | export * from "./services"; 12 | -------------------------------------------------------------------------------- /bitbit/src/features/chat/services/index.ts: -------------------------------------------------------------------------------- 1 | // Chat services will be exported here when implemented 2 | // Example: export { chatService } from './chatService'; 3 | // Example: export { socketService } from './socketService'; 4 | 5 | export {}; 6 | -------------------------------------------------------------------------------- /bitbit/src/features/community/types/index.ts: -------------------------------------------------------------------------------- 1 | // 社区相关类型定义 - 当前为空,可在此处添加类型 2 | // export interface CommunityPost { 3 | // id: string; 4 | // title: string; 5 | // content: string; 6 | // } 7 | 8 | // 导出空对象以避免编译错误 9 | export {}; 10 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/index.ts: -------------------------------------------------------------------------------- 1 | // Components 2 | export * from "./components"; 3 | 4 | // Types 5 | export * from "./types"; 6 | 7 | // Hooks 8 | export * from "./hooks"; 9 | 10 | // Services 11 | export * from "./services"; 12 | -------------------------------------------------------------------------------- /bitbit/.env.example: -------------------------------------------------------------------------------- 1 | # Environment Variables Example 2 | # Copy this file to .env and modify the values as needed 3 | 4 | # Show debug components (true/false) 5 | # Set to true for development/testing, false for production 6 | VITE_SHOW_DEBUG_COMPONENTS=true 7 | -------------------------------------------------------------------------------- /bitbit/src/pages/ProfileSettings.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Settings } from "../features/profile/components/Settings"; 3 | 4 | const ProfileSettings: React.FC = () => { 5 | return ; 6 | }; 7 | 8 | export default ProfileSettings; 9 | -------------------------------------------------------------------------------- /bitbit/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [ 3 | { 4 | "source": "/(.*)", 5 | "destination": "/index.html" 6 | } 7 | ], 8 | "buildCommand": "npm run build", 9 | "outputDirectory": "dist", 10 | "installCommand": "npm install" 11 | } 12 | -------------------------------------------------------------------------------- /bitbit/src/features/auth/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as LoginForm } from "./LoginForm"; 2 | export { default as RegisterForm } from "./RegisterForm"; 3 | export { default as AuthHeader } from "./AuthHeader"; 4 | export { default as UserAvatar } from "./UserAvatar"; 5 | -------------------------------------------------------------------------------- /bitbit/src/pages/ChatTestPage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ChatTestComponent from "@/features/chat/components/ChatTestComponent"; 3 | 4 | const ChatTestPage: React.FC = () => { 5 | return ; 6 | }; 7 | 8 | export default ChatTestPage; 9 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/components/Settings/SettingItem/index.ts: -------------------------------------------------------------------------------- 1 | export { SettingItem } from "./SettingItem"; 2 | export { SettingSwitch } from "./SettingSwitch"; 3 | export { SettingSelect } from "./SettingSelect"; 4 | export { SettingNavigation } from "./SettingNavigation"; 5 | -------------------------------------------------------------------------------- /bitbit/src/features/notifications/components/index.ts: -------------------------------------------------------------------------------- 1 | export { NotificationHeader } from "./NotificationHeader"; 2 | export { NotificationTabs } from "./NotificationTabs"; 3 | export { NotificationItem } from "./NotificationItem"; 4 | export { NotificationList } from "./NotificationList"; 5 | -------------------------------------------------------------------------------- /bitbit/src/features/community/hooks/index.ts: -------------------------------------------------------------------------------- 1 | // 社区相关hooks 2 | export { useCommunity } from "./useCommunity"; 3 | export type { CommunityPost } from "./useCommunity"; 4 | 5 | export { useCommunityUsers } from "./useCommunityUsers"; 6 | export type { CommunityUser } from "./useCommunityUsers"; 7 | -------------------------------------------------------------------------------- /bitbit/src/features/chat/index.ts: -------------------------------------------------------------------------------- 1 | // 导出所有组件 2 | export * from "./components"; 3 | 4 | // 导出类型定义 5 | export * from "./types"; 6 | 7 | // 导出store 8 | export { chatReducer } from "./store/chatSlice"; 9 | 10 | // 导出主要组件的便捷导入 11 | export { ChatContainer, ChatTestComponent } from "./components"; 12 | -------------------------------------------------------------------------------- /bitbit/src/shared/utils/cn.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | /** 5 | * 用于合并和处理CSS类名的工具函数 6 | * 结合clsx和tailwind-merge,确保类名合并的正确性 7 | */ 8 | export function cn(...inputs: ClassValue[]) { 9 | return twMerge(clsx(inputs)); 10 | } 11 | -------------------------------------------------------------------------------- /bitbit/src/features/chat/utils/index.ts: -------------------------------------------------------------------------------- 1 | // Chat utilities 2 | export { 3 | navigateToChat, 4 | navigateToChatFromUserCard, 5 | navigateToChatFromExchange, 6 | navigateToChatFromNotification, 7 | navigateToChatFromActivity, 8 | parseChatUrlParams, 9 | type ChatNavigationParams, 10 | } from "./navigation"; 11 | -------------------------------------------------------------------------------- /bitbit/src/features/exchange/components/PublishSteps/index.ts: -------------------------------------------------------------------------------- 1 | export { BasicInfoStep } from "./BasicInfoStep"; 2 | export { DetailInfoStep } from "./DetailInfoStep"; 3 | export { ProductDisplayStep } from "./ProductDisplayStep"; 4 | export { ContactInfoStep } from "./ContactInfoStep"; 5 | export { PreviewStep } from "./PreviewStep"; 6 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/components/Settings/modules/index.ts: -------------------------------------------------------------------------------- 1 | export { AccountSecurity } from "./AccountSecurity"; 2 | export { NotificationSettings } from "./NotificationSettings"; 3 | export { PrivacySettings } from "./PrivacySettings"; 4 | export { ApplicationSettings } from "./ApplicationSettings"; 5 | export { AboutSettings } from "./AboutSettings"; 6 | -------------------------------------------------------------------------------- /bitbit/src/features/exchange/components/index.ts: -------------------------------------------------------------------------------- 1 | // exchange 组件导出 2 | export { default as PublishWizard } from "./PublishWizard"; 3 | export { default as ExchangeList } from "./ExchangeList"; 4 | export { default as ExchangeFilters } from "./ExchangeFilters"; 5 | export { ExchangeCard } from "./ExchangeCard"; 6 | 7 | // 发布步骤组件 8 | export * from "./PublishSteps"; 9 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/components/Settings/modals/index.ts: -------------------------------------------------------------------------------- 1 | export { ChangePasswordModal } from "./ChangePasswordModal"; 2 | export { PhoneBindingModal } from "./PhoneBindingModal"; 3 | export { EmailBindingModal } from "./EmailBindingModal"; 4 | export { TwoFactorAuthModal } from "./TwoFactorAuthModal"; 5 | export { DeviceManagementModal } from "./DeviceManagementModal"; 6 | export { SecurityLogsModal } from "./SecurityLogsModal"; 7 | -------------------------------------------------------------------------------- /bitbit/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | bitbit-寻找你的伙伴 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /bitbit/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import { Provider } from "react-redux"; 4 | import { store } from "./store"; 5 | import "./index.css"; 6 | import App from "./App.tsx"; 7 | 8 | createRoot(document.getElementById("root")!).render( 9 | 10 | 11 | 12 | 13 | 14 | ); 15 | -------------------------------------------------------------------------------- /bitbit/src/features/community/components/PostDetail/index.ts: -------------------------------------------------------------------------------- 1 | export { default as PostDetailHeader } from "./PostDetailHeader"; 2 | export { default as PostDetailContent } from "./PostDetailContent"; 3 | export { default as PostDetailActions } from "./PostDetailActions"; 4 | export { default as PostDetailComments } from "./PostDetailComments"; 5 | export { default as PostDetailRecommendations } from "./PostDetailRecommendations"; 6 | export { default as ImageGallery } from "./ImageGallery"; 7 | -------------------------------------------------------------------------------- /bitbit/src/features/exchange/types/index.ts: -------------------------------------------------------------------------------- 1 | // exchange 类型定义导出 2 | export type { 3 | ExchangeItem, 4 | ExchangeCategory, 5 | ExchangeCondition, 6 | PublishFormData, 7 | ExchangeFormData, 8 | PurchaseFormData, 9 | ExchangeListProps, 10 | ExchangeCardProps, 11 | PublishStepProps, 12 | PublishStep, 13 | PublishStepConfig, 14 | ExchangeFilters as ExchangeFiltersType, 15 | // 订单相关类型 16 | OrderDetail, 17 | OrderProgress, 18 | OrderAction, 19 | } from "./types"; 20 | -------------------------------------------------------------------------------- /bitbit/src/features/exchange/components/OrderDetail/index.ts: -------------------------------------------------------------------------------- 1 | // OrderDetail 组件导出 2 | export { default as OrderStatusBanner } from "./OrderStatusBanner"; 3 | export { default as OrderItemInfo } from "./OrderItemInfo"; 4 | export { default as OrderTransactionDetails } from "./OrderTransactionDetails"; 5 | export { default as OrderOtherParty } from "./OrderOtherParty"; 6 | export { default as OrderProgressTimeline } from "./OrderProgressTimeline"; 7 | export { default as OrderActions } from "./OrderActions"; 8 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/components/ProfileEdit/index.ts: -------------------------------------------------------------------------------- 1 | export { ProfileEditNavigation } from "./ProfileEditNavigation"; 2 | export { BasicInfoForm } from "./BasicInfoForm"; 3 | export { InterestsForm } from "./InterestsForm"; 4 | export { PrivacyForm } from "./PrivacyForm"; 5 | export { SocialLinksForm } from "./SocialLinksForm"; 6 | export { VerificationForm } from "./VerificationForm"; 7 | export { useProfileEdit } from "./useProfileEdit"; 8 | 9 | export type { ProfileEditModule } from "./ProfileEditNavigation"; 10 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/components/index.ts: -------------------------------------------------------------------------------- 1 | // activities 组件导出 2 | // ActivityCard 已迁移到 @/components/ui/cards,请使用统一的UI组件 3 | 4 | // ActivityDetail 子组件导出 5 | export { 6 | ActivityHeader, 7 | ActivityBasicInfo, 8 | OrganizerInfo, 9 | ActivityContent, 10 | ActivityLocation, 11 | ParticipantStats, 12 | ParticipantAvatars, 13 | ParticipantDetails, 14 | ActivityActions, 15 | } from "./ActivityDetail"; 16 | 17 | export { ActivityForm } from "./ActivityForm"; 18 | export type { ActivityFormData, ActivityFormProps } from "./ActivityForm"; 19 | 20 | export { default as ActivityPreview } from "./ActivityPreview"; 21 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/components/ActivityForm/index.ts: -------------------------------------------------------------------------------- 1 | export { BasicInfoSection } from "./BasicInfoSection"; 2 | export { ImageUploadSection } from "./ImageUploadSection"; 3 | export { CategorySection } from "./CategorySection"; 4 | export { DescriptionSection } from "./DescriptionSection"; 5 | export { TimeLocationSection } from "./TimeLocationSection"; 6 | export { RegistrationSection } from "./RegistrationSection"; 7 | export { ScheduleSection } from "./ScheduleSection"; 8 | export { NoticesSection } from "./NoticesSection"; 9 | export { TagsSection } from "./TagsSection"; 10 | export { FormActions } from "./FormActions"; 11 | -------------------------------------------------------------------------------- /bitbit/src/features/community/components/CommunityHeader/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Breadcrumb } from "@/components/ui"; 3 | 4 | interface CommunityHeaderProps { 5 | className?: string; 6 | } 7 | 8 | const CommunityHeader: React.FC = ({ className }) => { 9 | const breadcrumbItems = [ 10 | { label: "首页", href: "/" }, 11 | { label: "社区", current: true }, 12 | ]; 13 | 14 | return ( 15 |
16 | 17 |
18 | ); 19 | }; 20 | 21 | export default CommunityHeader; 22 | -------------------------------------------------------------------------------- /bitbit/src/shared/hooks/index.ts: -------------------------------------------------------------------------------- 1 | // 导出所有通用 hooks 2 | export { useNavigationFilters } from "./useNavigationStore"; 3 | export { useSmartNavigation } from "./useSmartNavigation"; 4 | export { useConfirmExit } from "./useConfirmExit"; 5 | export { usePublishStatus } from "./usePublishStatus"; 6 | export { useExchangeActions } from "./useExchangeActions"; 7 | export type { 8 | ExchangeItem, 9 | UseExchangeActionsProps, 10 | UseExchangeActionsReturn, 11 | } from "./useExchangeActions"; 12 | // export { default as useLocalStorage } from './useLocalStorage' 13 | // export { default as useDebounce } from './useDebounce' 14 | // 根据实际文件添加更多导出 15 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/ThemeToggleButton.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useTheme } from "../../shared/hooks/useTheme"; 3 | 4 | export const ThemeToggleButton: React.FC = () => { 5 | const { theme, actualTheme, toggleTheme } = useTheme(); 6 | 7 | return ( 8 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/GradientBackground/GradientBackground.tsx: -------------------------------------------------------------------------------- 1 | import { type FC, type ReactNode } from "react"; 2 | 3 | interface GradientBackgroundProps { 4 | children: ReactNode; 5 | className?: string; 6 | } 7 | 8 | const GradientBackground: FC = ({ 9 | children, 10 | className = "", 11 | }) => { 12 | return ( 13 |
19 | {children} 20 |
21 | ); 22 | }; 23 | 24 | export default GradientBackground; 25 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/ContentFilter/exports.ts: -------------------------------------------------------------------------------- 1 | // 导出主要组件 2 | export { default as ContentFilter } from "./index.tsx"; 3 | export { default } from "./index.tsx"; 4 | 5 | // 导出类型 6 | export type { 7 | FilterOption, 8 | SortOption, 9 | FilterConfig, 10 | SortConfig, 11 | SearchConfig, 12 | ContentFilterProps, 13 | ProfileFilterConfigs, 14 | } from "./types"; 15 | 16 | // 导出配置 17 | export { 18 | profileFilterConfigs, 19 | favoritesConfig, 20 | postsConfig, 21 | tradesConfig, 22 | activitiesConfig, 23 | draftsConfig, 24 | getProfileFilterConfig, 25 | createCustomFilterFn, 26 | } from "./configs"; 27 | 28 | // 导出Hook 29 | export { useContentFilter } from "./useContentFilter"; 30 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/cards/index.ts: -------------------------------------------------------------------------------- 1 | // 统一的卡片组件导出 2 | export { ActivityCard } from "./ActivityCard"; 3 | export { PostCard } from "./PostCard"; 4 | export { UserCard } from "./UserCard"; 5 | 6 | // 导出类型 7 | export type { ActivityCardProps, Activity } from "./ActivityCard/types"; 8 | export type { PostCardProps, Post } from "./PostCard/types"; 9 | export type { UserCardProps, User } from "./UserCard/types"; 10 | 11 | // 基础卡片组件 12 | export { BaseCard } from "../BaseCard"; 13 | export type { 14 | BaseCardProps, 15 | CardLayout, 16 | CardActions, 17 | CardStats, 18 | CardMeta, 19 | } from "../BaseCard/types"; 20 | export { getCardVariantClasses, getLayoutClasses } from "../BaseCard/variants"; 21 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/components/Settings/index.ts: -------------------------------------------------------------------------------- 1 | // Settings 组件导出 2 | export { Settings } from "./SettingsLayout"; 3 | export { SettingsNavigation } from "./SettingsNavigation"; 4 | 5 | // Setting Item 组件导出 - 使用明确的重命名 6 | export { 7 | SettingItem as SettingsItemComponent, 8 | SettingSwitch, 9 | SettingSelect, 10 | SettingNavigation, 11 | } from "./SettingItem"; 12 | 13 | // Settings 模块导出 - 使用命名导出避免冲突 14 | export { 15 | AccountSecurity as SettingsAccountSecurity, 16 | NotificationSettings as SettingsNotificationSettings, 17 | PrivacySettings as SettingsPrivacySettings, 18 | ApplicationSettings as SettingsApplicationSettings, 19 | AboutSettings as SettingsAboutSettings, 20 | } from "./modules"; 21 | -------------------------------------------------------------------------------- /bitbit/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js' 2 | import globals from 'globals' 3 | import reactHooks from 'eslint-plugin-react-hooks' 4 | import reactRefresh from 'eslint-plugin-react-refresh' 5 | import tseslint from 'typescript-eslint' 6 | import { globalIgnores } from 'eslint/config' 7 | 8 | export default tseslint.config([ 9 | globalIgnores(['dist']), 10 | { 11 | files: ['**/*.{ts,tsx}'], 12 | extends: [ 13 | js.configs.recommended, 14 | tseslint.configs.recommended, 15 | reactHooks.configs['recommended-latest'], 16 | reactRefresh.configs.vite, 17 | ], 18 | languageOptions: { 19 | ecmaVersion: 2020, 20 | globals: globals.browser, 21 | }, 22 | }, 23 | ]) 24 | -------------------------------------------------------------------------------- /bitbit/src/components/common/index.ts: -------------------------------------------------------------------------------- 1 | // 通用组件导出 2 | export { default as BackButton } from "./BackButton"; 3 | export { default as ImageCarousel } from "./ImageCarousel"; 4 | export { default as FloatingBackButton } from "./FloatingBackButton"; 5 | export { default as ConfirmExitDialog } from "./ConfirmExitDialog"; 6 | export { default as ConfirmClearDialog } from "./ConfirmClearDialog"; 7 | export { default as ConfirmBatchDeleteDialog } from "./ConfirmBatchDeleteDialog"; 8 | 9 | export { default as ConfirmActionDialog } from "./ConfirmActionDialog"; 10 | export { PublishStatus } from "./PublishStatus"; 11 | export type { PublishStatusProps } from "./PublishStatus"; 12 | export type { ActionType } from "./ConfirmActionDialog"; 13 | -------------------------------------------------------------------------------- /bitbit/src/features/exchange/temp-exports.ts: -------------------------------------------------------------------------------- 1 | // Exchange功能模块统一导出文件 2 | 3 | // Hooks导出 4 | export { 5 | useExchangeItems, 6 | useExchangeItem, 7 | useExchangeRequest, 8 | useFavorites, 9 | useViewHistory, 10 | } from "./hooks/useExchange"; 11 | 12 | // 组件导出 13 | export { default as PublishWizard } from "./components/PublishWizard"; 14 | export { default as ExchangeList } from "./components/ExchangeList"; 15 | export { default as ExchangeFilters } from "./components/ExchangeFilters"; 16 | export { ExchangeCard } from "./components/ExchangeCard"; 17 | 18 | // 发布步骤组件 19 | export * from "./components/PublishSteps"; 20 | 21 | // 类型导出 22 | export * from "./types/types"; 23 | 24 | // 常量导出 25 | export * from "./constants"; 26 | -------------------------------------------------------------------------------- /bitbit/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import react from "@vitejs/plugin-react"; 3 | import path from "path"; 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react()], 8 | resolve: { 9 | alias: { 10 | "@": path.resolve(__dirname, "./src"), 11 | "@/components": path.resolve(__dirname, "./src/components"), 12 | "@/features": path.resolve(__dirname, "./src/features"), 13 | "@/shared": path.resolve(__dirname, "./src/shared"), 14 | "@/pages": path.resolve(__dirname, "./src/pages"), 15 | "@/assets": path.resolve(__dirname, "./src/assets"), 16 | "@/store": path.resolve(__dirname, "./src/store"), 17 | }, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/components/ActivityDetail/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ActivityHeader } from "./ActivityHeader"; 2 | export { default as ActivityBasicInfo } from "./ActivityBasicInfo"; 3 | export { default as OrganizerInfo } from "./OrganizerInfo"; 4 | export { default as ActivityContent } from "./ActivityContent"; 5 | export { default as ActivityLocation } from "./ActivityLocation"; 6 | export { default as ParticipantStats } from "./ParticipantStats"; 7 | export { default as ParticipantAvatars } from "./ParticipantAvatars"; 8 | export { default as ParticipantCard } from "./ParticipantCard"; 9 | export { default as ParticipantDetails } from "./ParticipantDetails"; 10 | export { default as ActivityActions } from "./ActivityActions"; 11 | -------------------------------------------------------------------------------- /bitbit/src/features/exchange/index.ts: -------------------------------------------------------------------------------- 1 | // exchange 功能模块导出 2 | 3 | // 组件导出 4 | export { default as PublishWizard } from "./components/PublishWizard"; 5 | export { default as ExchangeList } from "./components/ExchangeList"; 6 | export { default as ExchangeFiltersComponent } from "./components/ExchangeFilters"; 7 | export { ExchangeCard } from "./components/ExchangeCard"; 8 | 9 | // 步骤组件 10 | export * from "./components/PublishSteps"; 11 | 12 | // 订单详情组件 13 | export * from "./components/OrderDetail"; 14 | 15 | // 页面组件 16 | export { default as OrderDetailPage } from "./pages/OrderDetailPage"; 17 | 18 | // hooks导出 19 | export * from "./hooks/index"; 20 | 21 | // 类型导出 22 | export * from "./types/index"; 23 | 24 | // 常量导出 25 | export * from "./constants"; 26 | -------------------------------------------------------------------------------- /bitbit/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2023", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "verbatimModuleSyntax": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "erasableSyntaxOnly": true, 21 | "noFallthroughCasesInSwitch": true, 22 | "noUncheckedSideEffectImports": true 23 | }, 24 | "include": ["vite.config.ts"] 25 | } 26 | -------------------------------------------------------------------------------- /bitbit/src/features/community/components/index.ts: -------------------------------------------------------------------------------- 1 | // community 组件导出 2 | // PostCard 已迁移到 @/components/ui/cards,请使用统一的UI组件 3 | export * from "./PostDetail"; 4 | 5 | export { default as CommunityPostForm } from "./CommunityPostForm"; 6 | export type { 7 | CommunityPostFormData, 8 | CommunityPostFormProps, 9 | } from "./CommunityPostForm"; 10 | 11 | export { default as PostPreview } from "./PostPreview"; 12 | 13 | // 新增的Community页面组件 14 | export { default as CommunityHeader } from "./CommunityHeader"; 15 | export { default as CommunitySearch } from "./CommunitySearch"; 16 | export { default as CategorySidebar } from "./CategorySidebar"; 17 | export { default as CommunitySidebar } from "./CommunitySidebar"; 18 | export { default as PostList } from "./PostList"; 19 | -------------------------------------------------------------------------------- /bitbit/src/pages/FollowListPage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useParams, useLocation } from "react-router-dom"; 3 | import { FollowList } from "@/features/profile/components/FollowList"; 4 | 5 | /** 6 | * 关注/粉丝列表页面 7 | * 根据路径判断显示关注列表还是粉丝列表 8 | */ 9 | export const FollowListPage: React.FC = () => { 10 | const { userId } = useParams<{ userId?: string }>(); 11 | const location = useLocation(); 12 | 13 | // 根据路径判断列表类型 14 | const isFollowingList = location.pathname.includes("following"); 15 | const type = isFollowingList ? "following" : "followers"; 16 | 17 | return ( 18 |
19 | 20 |
21 | ); 22 | }; 23 | 24 | export default FollowListPage; 25 | -------------------------------------------------------------------------------- /bitbit/src/shared/components/index.ts: -------------------------------------------------------------------------------- 1 | // 用户卡片弹出框组件 2 | export { default as UserCardPopover } from "./UserCardPopover"; 3 | export type { UserInfo } from "./UserCardPopover"; 4 | 5 | // 其他组件 6 | export { default as ParticipantCardEnhanced } from "./ParticipantCardEnhanced"; 7 | export { default as TagsInput } from "./TagsInput"; 8 | 9 | // 搜索和筛选相关组件 10 | export { SearchBar } from "./SearchBar"; 11 | export type { SearchBarProps } from "./SearchBar"; 12 | 13 | export { SortSelector } from "./SortSelector"; 14 | export type { SortSelectorProps, SortOption } from "./SortSelector"; 15 | 16 | export { SimpleSearchFilter } from "./SimpleSearchFilter"; 17 | export type { SimpleSearchFilterProps } from "./SimpleSearchFilter"; 18 | 19 | export { TabFilter } from "./TabFilter"; 20 | export type { TabFilterProps, TabOption } from "./TabFilter"; 21 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/components/index.ts: -------------------------------------------------------------------------------- 1 | export { UserProfile } from "./UserProfile"; 2 | export { ProfileTabs } from "./ProfileTabs"; 3 | export { ActivityFilter } from "./ActivityFilter"; 4 | export { OtherUserActivityFilter } from "./OtherUserActivityFilter"; 5 | export { AchievementBadges } from "./AchievementBadges"; 6 | export { QuickAccess } from "./QuickAccess"; 7 | export { LoadingState } from "./LoadingState"; 8 | export { Pagination } from "./Pagination"; 9 | export { ActivityNotificationModal } from "./ActivityNotificationModal"; 10 | export { FollowList } from "./FollowList"; 11 | export { OtherUserProfilePage } from "./OtherUserProfile"; 12 | export { OtherUserProfileHeader } from "./OtherUserProfileHeader"; 13 | 14 | // ProfileEdit 相关组件 15 | export * from "./ProfileEdit"; 16 | 17 | // Settings 相关组件 18 | export * from "./Settings"; 19 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/cards/ActivityCard/README.md: -------------------------------------------------------------------------------- 1 | /\*\* 2 | 3 | - ActivityCard Component Architecture 4 | - 5 | - 这是一个复杂但功能完整的活动卡片组件,支持多种布局和状态。 6 | - 7 | - ## 组件特性 8 | - - 支持 5 种布局模式:default, horizontal, list, compact, minimal 9 | - - 统一的状态管理使用 activityUtils 10 | - - 高度可配置的显示选项 11 | - - 完整的用户交互支持 12 | - 13 | - ## 代码结构 14 | - 1. 数据适配 (lines 50-70) 15 | - 2. 配置获取 (lines 71-220) 16 | - 3. 状态计算 (lines 221-260) 17 | - 4. 事件处理 (lines 261-270) 18 | - 5. 渲染函数 (lines 271-600) 19 | - - renderImages: 图片渲染 20 | - - renderHeader: 头部信息 21 | - - renderContent: 主要内容 22 | - - renderActions: 操作按钮 23 | - 6. 主渲染逻辑 (lines 601-950) 24 | - 25 | - ## 性能考虑 26 | - - 组件使用了合理的条件渲染 27 | - - 避免了不必要的重新计算 28 | - - 使用了 useMemo 优化(如果需要的话) 29 | - 30 | - ## 维护建议 31 | - - 避免在此文件中添加新的布局模式 32 | - - 新的状态逻辑应该添加到 activityUtils 33 | - - 样式更改优先考虑使用 CSS 变量 34 | \*/ 35 | 36 | // 当前代码行数: ~950 行 37 | // 复杂度: 高,但可维护 38 | // 状态: 稳定,建议保持现状 39 | -------------------------------------------------------------------------------- /bitbit/src/config/branch.config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 分支特定配置 3 | * 用于控制不同分支(dev/main)的功能差异 4 | */ 5 | 6 | // 获取当前分支信息(如果可用) 7 | const getCurrentBranch = () => { 8 | // 在生产环境中,这可以通过构建时注入的环境变量来获取 9 | return import.meta.env.VITE_CURRENT_BRANCH || "dev"; 10 | }; 11 | 12 | // 检查是否为dev分支 13 | const isDevBranch = () => { 14 | const branch = getCurrentBranch(); 15 | return branch === "dev" || branch === "development"; 16 | }; 17 | 18 | // 检查是否为生产环境 19 | const isProduction = () => { 20 | return import.meta.env.PROD; 21 | }; 22 | 23 | export const branchConfig = { 24 | // 当前分支 25 | currentBranch: getCurrentBranch(), 26 | 27 | // 是否为dev分支 28 | isDevBranch: isDevBranch(), 29 | 30 | // 是否为生产环境 31 | isProduction: isProduction(), 32 | 33 | // 是否显示调试组件 34 | // dev分支或开发环境显示,生产环境的主分支隐藏 35 | showDebugComponents: isDevBranch() || !isProduction(), 36 | } as const; 37 | 38 | export default branchConfig; 39 | -------------------------------------------------------------------------------- /bitbit/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | # Development documentation 27 | docs/development/ 28 | docs/ 29 | 30 | # Environment files 31 | .env 32 | .env.local 33 | .env.development.local 34 | .env.test.local 35 | .env.production.local 36 | 37 | # Test coverage 38 | coverage/ 39 | *.lcov 40 | 41 | # Temporary files 42 | *.tmp 43 | *.temp 44 | *_temp.* 45 | *_backup.* 46 | *_old.* 47 | 48 | # Build artifacts 49 | build/ 50 | out/ 51 | 52 | # Cache directories 53 | .cache/ 54 | .parcel-cache/ 55 | .eslintcache 56 | 57 | # OS generated files 58 | Thumbs.db 59 | *.DS_Store 60 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/components/Settings/SettingItem/SettingSwitch.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { SettingItem } from "./SettingItem"; 3 | import { Switch } from "../../../../../components/ui/Switch"; 4 | 5 | interface SettingSwitchProps { 6 | icon?: string; 7 | iconColor?: string; 8 | title: string; 9 | description?: string; 10 | checked: boolean; 11 | disabled?: boolean; 12 | onChange: (checked: boolean) => void; 13 | } 14 | 15 | export const SettingSwitch: React.FC = ({ 16 | icon, 17 | iconColor, 18 | title, 19 | description, 20 | checked, 21 | disabled = false, 22 | onChange, 23 | }) => { 24 | return ( 25 | 31 | 32 | 33 | ); 34 | }; 35 | -------------------------------------------------------------------------------- /bitbit/src/config/dev.config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 开发环境配置 3 | * 用于控制开发时的功能开关 4 | */ 5 | 6 | import { branchConfig } from "./branch.config"; 7 | 8 | // 检查是否为开发环境 9 | const isDevelopment = import.meta.env.MODE === "development"; 10 | 11 | // 检查环境变量设置 12 | const envShowDebugComponents = import.meta.env.VITE_SHOW_DEBUG_COMPONENTS; 13 | 14 | // 决定是否显示调试组件的逻辑: 15 | // 1. 如果明确设置了环境变量,使用环境变量的值 16 | // 2. 否则,dev分支或开发环境下显示,生产环境的main分支隐藏 17 | const shouldShowDebugComponents = 18 | envShowDebugComponents !== undefined 19 | ? envShowDebugComponents === "true" 20 | : branchConfig.showDebugComponents; 21 | 22 | export const devConfig = { 23 | // 是否显示调试组件(右下角的测试组件) 24 | showDebugComponents: shouldShowDebugComponents, 25 | 26 | // 其他开发配置 27 | enableConsoleLogging: isDevelopment, 28 | enableDevTools: isDevelopment, 29 | 30 | // 分支信息 31 | branch: branchConfig.currentBranch, 32 | isDevBranch: branchConfig.isDevBranch, 33 | } as const; 34 | 35 | export default devConfig; 36 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/SectionHeader/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Button from "../Button"; 3 | import { cn } from "@/shared/utils/cn"; 4 | 5 | export interface SectionHeaderProps { 6 | title: string; 7 | actionText?: string; 8 | onActionClick?: () => void; 9 | className?: string; 10 | } 11 | 12 | const SectionHeader: React.FC = ({ 13 | title, 14 | actionText, 15 | onActionClick, 16 | className, 17 | }) => { 18 | return ( 19 |
20 |

{title}

21 | {actionText && ( 22 | 30 | )} 31 |
32 | ); 33 | }; 34 | 35 | export default SectionHeader; 36 | -------------------------------------------------------------------------------- /bitbit/src/components/debug/DebugInfo.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * 开发调试信息组件 3 | * 仅在开发环境显示当前配置状态 4 | */ 5 | 6 | import React from "react"; 7 | import { devConfig } from "@/config/dev.config"; 8 | 9 | const DebugInfo: React.FC = () => { 10 | // 只在开发环境显示 11 | if (import.meta.env.PROD) { 12 | return null; 13 | } 14 | 15 | return ( 16 |
17 |
Debug Info:
18 |
Mode: {import.meta.env.MODE}
19 |
20 | Show Debug Components:{" "} 21 | {devConfig.showDebugComponents ? "true" : "false"} 22 |
23 |
Branch: {devConfig.branch}
24 |
Is Dev Branch: {devConfig.isDevBranch ? "true" : "false"}
25 |
26 | ENV Variable:{" "} 27 | {import.meta.env.VITE_SHOW_DEBUG_COMPONENTS || "undefined"} 28 |
29 |
30 | ); 31 | }; 32 | 33 | export default DebugInfo; 34 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/SearchBar/index.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | const SearchBar = () => { 4 | const [searchText, setSearchText] = useState(""); 5 | 6 | const handleSearch = (e: React.FormEvent) => { 7 | e.preventDefault(); 8 | // TODO: 实现搜索功能 9 | console.log("Search for:", searchText); 10 | }; 11 | 12 | return ( 13 |
14 |
15 | setSearchText(e.target.value)} 20 | className="w-full px-5 py-3 border border-gray-200 rounded-full text-body text-text-primary placeholder:text-text-tertiary focus:border-primary-500 focus:ring-2 focus:ring-primary-100 outline-none transition-colors duration-250" 21 | /> 22 |
23 |
24 | ); 25 | }; 26 | 27 | export default SearchBar; 28 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/components/ActivityForm/FormActions.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button } from "@/components/ui"; 3 | 4 | interface FormActionsProps { 5 | isValid: boolean; 6 | isSubmitting: boolean; 7 | onSubmit: () => void; 8 | onCancel: () => void; 9 | } 10 | 11 | export const FormActions: React.FC = ({ 12 | isValid, 13 | isSubmitting, 14 | onSubmit, 15 | onCancel, 16 | }) => { 17 | return ( 18 |
19 | 27 | 36 |
37 | ); 38 | }; 39 | 40 | export default FormActions; 41 | -------------------------------------------------------------------------------- /bitbit/src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { configureStore } from "@reduxjs/toolkit"; 2 | import { setupListeners } from "@reduxjs/toolkit/query"; 3 | import { authReducer } from "./slices/authSlice"; 4 | import { uiReducer } from "./slices/uiSlice"; 5 | import { userReducer } from "./slices/userSlice"; 6 | import { settingsReducer } from "./slices/settingsSlice"; 7 | import { chatReducer } from "@/features/chat/store/chatSlice"; 8 | 9 | export const store = configureStore({ 10 | reducer: { 11 | auth: authReducer, 12 | ui: uiReducer, 13 | user: userReducer, 14 | settings: settingsReducer, 15 | chat: chatReducer, 16 | }, 17 | middleware: (getDefaultMiddleware) => 18 | getDefaultMiddleware({ 19 | serializableCheck: { 20 | // Ignore these paths in the state 21 | ignoredActions: ["persist/PERSIST"], 22 | ignoredPaths: ["ui.toast"], 23 | }, 24 | }), 25 | }); 26 | 27 | setupListeners(store.dispatch); 28 | 29 | export type RootState = ReturnType; 30 | export type AppDispatch = typeof store.dispatch; 31 | -------------------------------------------------------------------------------- /bitbit/src/components/common/PublishStatus/types.ts: -------------------------------------------------------------------------------- 1 | export interface PublishStatusProps { 2 | status: "idle" | "loading" | "success" | "error"; 3 | error?: string; 4 | onRetry: () => void; 5 | onReset: () => void; 6 | successConfig: { 7 | title: string; 8 | description: string; 9 | publishedItemId?: string; // 发布成功后的ID 10 | previewData: { 11 | title: string; 12 | category?: string; 13 | condition?: string; 14 | price?: number; 15 | image?: string | File; 16 | type: "activity" | "post" | "item"; 17 | }; 18 | // 完整的表单数据,用于渲染详细预览 19 | fullPreviewData?: T; 20 | actions: { 21 | primary: { 22 | label: string; 23 | href?: string; 24 | generateHref?: (id: string) => string; 25 | }; 26 | secondary: { 27 | label: string; 28 | href: string; 29 | }; 30 | tertiary?: { 31 | label: string; 32 | onClick: () => void; 33 | }; 34 | }; 35 | }; 36 | loadingConfig: { 37 | title: string; 38 | description: string; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /bitbit/src/pages/Login.tsx: -------------------------------------------------------------------------------- 1 | import { type FC } from "react"; 2 | import { GradientBackground } from "@/components/ui"; 3 | import { AuthHeader, LoginForm } from "@/features/auth/components"; 4 | 5 | const Login: FC = () => { 6 | return ( 7 | 8 |
9 | 10 | 11 |
12 | 13 |
14 | 15 | {/* 底部装饰 */} 16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | ); 25 | }; 26 | 27 | export default Login; 28 | -------------------------------------------------------------------------------- /bitbit/src/pages/Register.tsx: -------------------------------------------------------------------------------- 1 | import { type FC } from "react"; 2 | import { GradientBackground } from "@/components/ui"; 3 | import { AuthHeader, RegisterForm } from "@/features/auth/components"; 4 | 5 | const Register: FC = () => { 6 | return ( 7 | 8 |
9 | 10 | 11 |
12 | 13 |
14 | 15 | {/* 底部装饰 */} 16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | ); 25 | }; 26 | 27 | export default Register; 28 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/utils/index.ts: -------------------------------------------------------------------------------- 1 | import type { Activity } from "../types"; 2 | 3 | /** 4 | * 格式化日期显示 5 | */ 6 | export const formatDate = (dateStr: string): string => { 7 | const date = new Date(dateStr); 8 | const now = new Date(); 9 | const diffTime = date.getTime() - now.getTime(); 10 | const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); 11 | 12 | if (diffDays < 0) { 13 | return "已结束"; 14 | } else if (diffDays === 0) { 15 | return "今天"; 16 | } else if (diffDays === 1) { 17 | return "明天"; 18 | } else { 19 | return `${diffDays}天后`; 20 | } 21 | }; 22 | 23 | /** 24 | * 获取活动状态的显示文本 25 | */ 26 | export const getActivityStatusText = (status: Activity["status"]): string => { 27 | switch (status) { 28 | case "registered": 29 | return "已报名"; 30 | case "organized": 31 | return "已组织"; 32 | case "ended": 33 | return "已结束"; 34 | default: 35 | return "未知"; 36 | } 37 | }; 38 | 39 | /** 40 | * 计算经验值百分比 41 | */ 42 | export const calculateExpPercentage = ( 43 | current: number, 44 | total: number 45 | ): number => { 46 | return Math.max(0, Math.min(100, (current / total) * 100)); 47 | }; 48 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/EmptyState/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button } from "@/components/ui"; 3 | 4 | export interface EmptyStateProps { 5 | icon?: string | React.ReactNode; 6 | title: string; 7 | description?: string; 8 | actionText?: string; 9 | onAction?: () => void; 10 | className?: string; 11 | } 12 | 13 | export const EmptyState: React.FC = ({ 14 | icon = "📭", 15 | title, 16 | description, 17 | actionText, 18 | onAction, 19 | className = "", 20 | }) => { 21 | return ( 22 |
23 |
24 | {typeof icon === "string" ? icon : icon} 25 |
26 |

{title}

27 | {description &&

{description}

} 28 | {actionText && onAction && ( 29 | 35 | )} 36 |
37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/Container/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { cn } from "@/shared/utils/cn"; 3 | 4 | export interface ContainerProps extends React.HTMLAttributes { 5 | size?: "sm" | "md" | "lg" | "xl" | "full"; 6 | padding?: "none" | "sm" | "md" | "lg"; 7 | center?: boolean; 8 | } 9 | 10 | const Container: React.FC = ({ 11 | className, 12 | size = "lg", 13 | padding = "md", 14 | center = true, 15 | children, 16 | ...props 17 | }) => { 18 | const sizeConfig = { 19 | sm: "max-w-screen-sm", 20 | md: "max-w-screen-md", 21 | lg: "max-w-screen-lg", 22 | xl: "max-w-screen-xl", 23 | full: "max-w-full", 24 | }; 25 | 26 | const paddingConfig = { 27 | none: "", 28 | sm: "px-4", 29 | md: "px-6", 30 | lg: "px-8", 31 | }; 32 | 33 | const centerConfig = center ? "mx-auto" : ""; 34 | 35 | return ( 36 |
46 | {children} 47 |
48 | ); 49 | }; 50 | 51 | export default Container; 52 | -------------------------------------------------------------------------------- /bitbit/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2022", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2022", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "verbatimModuleSyntax": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "erasableSyntaxOnly": true, 23 | "noFallthroughCasesInSwitch": true, 24 | "noUncheckedSideEffectImports": true, 25 | 26 | /* Path mapping */ 27 | "baseUrl": ".", 28 | "paths": { 29 | "@/*": ["./src/*"], 30 | "@/components/*": ["./src/components/*"], 31 | "@/features/*": ["./src/features/*"], 32 | "@/shared/*": ["./src/shared/*"], 33 | "@/pages/*": ["./src/pages/*"], 34 | "@/assets/*": ["./src/assets/*"], 35 | "@/store/*": ["./src/store/*"] 36 | } 37 | }, 38 | "include": ["src"] 39 | } 40 | -------------------------------------------------------------------------------- /bitbit/src/features/chat/components/index.ts: -------------------------------------------------------------------------------- 1 | // 聊天核心组件 2 | export { default as ChatContainer } from "./ChatContainer"; 3 | export { default as ChatHeader } from "./ChatHeader"; 4 | export { default as ChatMain } from "./ChatMain"; 5 | export { default as ChatPageHeader } from "./ChatPageHeader"; 6 | export { default as ChatTestComponent } from "./ChatTestComponent"; 7 | 8 | // 消息相关组件 9 | export { default as MessageList } from "./MessageList"; 10 | export { default as MessageBubble } from "./MessageBubble"; 11 | export { default as MessageInput } from "./MessageInput"; 12 | export { default as UnreadMessagesBadge } from "./UnreadMessagesBadge"; 13 | 14 | // 会话相关组件 15 | export { default as ConversationList } from "./ConversationList"; 16 | export { default as ConversationListHeader } from "./ConversationListHeader"; 17 | 18 | // 群聊相关组件 19 | export { default as GroupSettings } from "./GroupSettings"; 20 | export { default as GroupMembersList } from "./GroupMembersList"; 21 | export { default as GroupDismissedNotice } from "./GroupDismissedNotice"; 22 | export { default as GroupChatHeader } from "./GroupChatHeader"; 23 | export { default as CreateGroupChat } from "./CreateGroupChat"; 24 | 25 | // 导出组件的类型 26 | export type { ChatContainerRef } from "./ChatContainer"; 27 | -------------------------------------------------------------------------------- /bitbit/src/store/slices/uiSlice.ts: -------------------------------------------------------------------------------- 1 | import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; 2 | 3 | interface UiState { 4 | theme: "light" | "dark"; 5 | sidebarOpen: boolean; 6 | toast: { 7 | show: boolean; 8 | message: string; 9 | type: "success" | "error" | "info" | "warning"; 10 | }; 11 | } 12 | 13 | const initialState: UiState = { 14 | theme: "light", 15 | sidebarOpen: false, 16 | toast: { 17 | show: false, 18 | message: "", 19 | type: "info", 20 | }, 21 | }; 22 | 23 | const uiSlice = createSlice({ 24 | name: "ui", 25 | initialState, 26 | reducers: { 27 | toggleTheme: (state) => { 28 | state.theme = state.theme === "light" ? "dark" : "light"; 29 | }, 30 | toggleSidebar: (state) => { 31 | state.sidebarOpen = !state.sidebarOpen; 32 | }, 33 | showToast: ( 34 | state, 35 | action: PayloadAction> 36 | ) => { 37 | state.toast = { 38 | ...action.payload, 39 | show: true, 40 | }; 41 | }, 42 | hideToast: (state) => { 43 | state.toast.show = false; 44 | }, 45 | }, 46 | }); 47 | 48 | export const { toggleTheme, toggleSidebar, showToast, hideToast } = 49 | uiSlice.actions; 50 | export const uiReducer = uiSlice.reducer; 51 | -------------------------------------------------------------------------------- /bitbit/src/features/notifications/types/index.ts: -------------------------------------------------------------------------------- 1 | export interface Notification { 2 | id: string; 3 | type: "activity" | "social" | "system" | "message"; 4 | title: string; 5 | content: string; 6 | time: string; 7 | isRead: boolean; 8 | avatar?: string; 9 | actionUrl?: string; 10 | createdAt: string; 11 | updatedAt?: string; 12 | // 消息通知聚合相关字段 13 | messageData?: { 14 | senders: Array<{ 15 | userId: string; 16 | userName: string; 17 | userAvatar?: string; 18 | lastMessage: string; 19 | timestamp: string; 20 | }>; 21 | totalCount: number; 22 | lastSenderName: string; 23 | lastMessage: string; 24 | lastSenderId: string; 25 | lastSenderAvatar?: string; 26 | }; 27 | } 28 | 29 | export type NotificationType = "all" | "activity" | "social" | "system"; 30 | 31 | export interface NotificationStats { 32 | total: number; 33 | unread: number; 34 | byType: Record; 35 | } 36 | 37 | export interface NotificationFilter { 38 | type: NotificationType; 39 | onlyUnread?: boolean; 40 | } 41 | 42 | export interface NotificationActions { 43 | markAsRead: (id: string) => void; 44 | markAllAsRead: () => void; 45 | clearAllNotifications: () => void; 46 | deleteNotification: (id: string) => void; 47 | } 48 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/cards/PostCard/types.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | BaseCardProps, 3 | CardLayout, 4 | CardActions, 5 | } from "../../BaseCard/types"; 6 | 7 | export interface Post { 8 | id: string; 9 | author: { 10 | name: string; 11 | avatar?: string; 12 | isVerified?: boolean; 13 | }; 14 | content: string; 15 | images?: string[]; 16 | category?: "music" | "food" | "learning" | "reading"; 17 | tags?: string[]; 18 | publishTime: string; 19 | likes: number; 20 | comments: number; 21 | shares: number; 22 | isLiked?: boolean; 23 | isBookmarked?: boolean; 24 | } 25 | 26 | export interface PostCardProps 27 | extends Omit, 28 | CardLayout, 29 | CardActions { 30 | post: Post; 31 | 32 | // 帖子特定的回调 33 | onLike?: () => void; 34 | onComment?: () => void; 35 | onShare?: () => void; 36 | onBookmark?: () => void; 37 | onTagClick?: (tag: string) => void; 38 | onViewDetail?: () => void; 39 | 40 | // 管理相关回调(仅对自己的帖子显示) 41 | onEdit?: () => void; 42 | onDelete?: () => void; 43 | 44 | // 显示控制 45 | showAuthor?: boolean; 46 | showImages?: boolean; 47 | showCategory?: boolean; 48 | showTags?: boolean; 49 | showPublishTime?: boolean; 50 | showInteractionStats?: boolean; 51 | showManagementActions?: boolean; // 是否显示编辑和删除按钮 52 | } 53 | -------------------------------------------------------------------------------- /bitbit/src/components/ui/Grid/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { cn } from "@/shared/utils/cn"; 3 | 4 | export interface GridProps extends React.HTMLAttributes { 5 | cols?: 1 | 2 | 3 | 4 | 5 | 6; 6 | gap?: "none" | "sm" | "md" | "lg" | "xl"; 7 | responsive?: boolean; 8 | } 9 | 10 | const Grid: React.FC = ({ 11 | className, 12 | cols = 1, 13 | gap = "md", 14 | responsive = true, 15 | children, 16 | ...props 17 | }) => { 18 | const colsConfig = { 19 | 1: "grid-cols-1", 20 | 2: responsive ? "grid-cols-1 md:grid-cols-2" : "grid-cols-2", 21 | 3: responsive ? "grid-cols-1 md:grid-cols-2 lg:grid-cols-3" : "grid-cols-3", 22 | 4: responsive ? "grid-cols-1 md:grid-cols-2 lg:grid-cols-4" : "grid-cols-4", 23 | 5: responsive ? "grid-cols-1 md:grid-cols-3 lg:grid-cols-5" : "grid-cols-5", 24 | 6: responsive ? "grid-cols-1 md:grid-cols-3 lg:grid-cols-6" : "grid-cols-6", 25 | }; 26 | 27 | const gapConfig = { 28 | none: "gap-0", 29 | sm: "gap-2", 30 | md: "gap-4", 31 | lg: "gap-6", 32 | xl: "gap-8", 33 | }; 34 | 35 | return ( 36 |
40 | {children} 41 |
42 | ); 43 | }; 44 | 45 | export default Grid; 46 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/components/ActivityForm/CategorySection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Card, CardContent, CategorySelector } from "@/components/ui"; 3 | import type { ActivityFormData } from "../ActivityForm"; 4 | 5 | interface CategorySectionProps { 6 | formData: ActivityFormData; 7 | onFieldChange: ( 8 | field: K, 9 | value: ActivityFormData[K] 10 | ) => void; 11 | onFieldFocus: (fieldName: string) => void; 12 | } 13 | 14 | export const CategorySection: React.FC = ({ 15 | formData, 16 | onFieldChange, 17 | onFieldFocus, 18 | }) => { 19 | return ( 20 | 21 | 22 |
23 | 26 |
onFieldFocus("category")}> 27 | onFieldChange("category", categoryId)} 30 | allowCustom={true} 31 | /> 32 |
33 |
34 |
35 |
36 | ); 37 | }; 38 | 39 | export default CategorySection; 40 | -------------------------------------------------------------------------------- /bitbit/src/shared/config/constants.ts: -------------------------------------------------------------------------------- 1 | // API endpoints 2 | export const API_BASE_URL = 3 | import.meta.env.VITE_API_BASE_URL || "http://localhost:3000/api"; 4 | 5 | // Authentication 6 | export const TOKEN_KEY = "bitbit_token"; 7 | export const USER_KEY = "bitbit_user"; 8 | 9 | // Pagination 10 | export const DEFAULT_PAGE_SIZE = 10; 11 | export const INFINITE_SCROLL_THRESHOLD = 0.8; 12 | 13 | // File upload 14 | export const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB 15 | export const ALLOWED_FILE_TYPES = ["image/jpeg", "image/png", "image/gif"]; 16 | 17 | // Date format 18 | export const DEFAULT_DATE_FORMAT = "YYYY-MM-DD HH:mm:ss"; 19 | 20 | // Validation 21 | export const PASSWORD_MIN_LENGTH = 8; 22 | export const USERNAME_MIN_LENGTH = 3; 23 | export const USERNAME_MAX_LENGTH = 20; 24 | 25 | // UI Constants 26 | export const MOBILE_BREAKPOINT = 768; 27 | export const TABLET_BREAKPOINT = 1024; 28 | export const DESKTOP_BREAKPOINT = 1280; 29 | 30 | // Cache 31 | export const CACHE_TTL = 5 * 60 * 1000; // 5 minutes 32 | export const STALE_TIME = 60 * 1000; // 1 minute 33 | 34 | // Error Messages 35 | export const ERROR_MESSAGES = { 36 | NETWORK_ERROR: "网络连接失败,请检查网络后重试", 37 | UNAUTHORIZED: "请先登录后再进行操作", 38 | FORBIDDEN: "您没有权限执行此操作", 39 | NOT_FOUND: "请求的资源不存在", 40 | SERVER_ERROR: "服务器出现错误,请稍后重试", 41 | VALIDATION_ERROR: "输入的信息有误,请检查后重试", 42 | } as const; 43 | -------------------------------------------------------------------------------- /bitbit/src/features/profile/components/Settings/SettingItem/SettingSelect.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { SettingItem } from "./SettingItem"; 3 | 4 | interface SettingSelectProps { 5 | icon?: string; 6 | iconColor?: string; 7 | title: string; 8 | description?: string; 9 | value: string; 10 | options: { label: string; value: string }[]; 11 | disabled?: boolean; 12 | onChange: (value: string) => void; 13 | } 14 | 15 | export const SettingSelect: React.FC = ({ 16 | icon, 17 | iconColor, 18 | title, 19 | description, 20 | value, 21 | options, 22 | disabled = false, 23 | onChange, 24 | }) => { 25 | return ( 26 | 32 | 44 | 45 | ); 46 | }; 47 | -------------------------------------------------------------------------------- /bitbit/src/shared/utils/date.ts: -------------------------------------------------------------------------------- 1 | import { DEFAULT_DATE_FORMAT } from "../config/constants"; 2 | import dayjs from "dayjs"; 3 | import relativeTime from "dayjs/plugin/relativeTime"; 4 | dayjs.extend(relativeTime); 5 | 6 | export const formatDate = ( 7 | date: Date | string, 8 | format = DEFAULT_DATE_FORMAT 9 | ): string => { 10 | return dayjs(date).format(format); 11 | }; 12 | 13 | export const isValidDate = (date: Date | string): boolean => { 14 | return dayjs(date).isValid(); 15 | }; 16 | 17 | export const getRelativeTime = (date: Date | string): string => { 18 | return dayjs(date).fromNow(); 19 | }; 20 | 21 | export const addDays = (date: Date | string, days: number): Date => { 22 | return dayjs(date).add(days, "day").toDate(); 23 | }; 24 | 25 | export const subtractDays = (date: Date | string, days: number): Date => { 26 | return dayjs(date).subtract(days, "day").toDate(); 27 | }; 28 | 29 | export const isSameDay = ( 30 | date1: Date | string, 31 | date2: Date | string 32 | ): boolean => { 33 | return dayjs(date1).isSame(date2, "day"); 34 | }; 35 | 36 | export const isBefore = ( 37 | date1: Date | string, 38 | date2: Date | string 39 | ): boolean => { 40 | return dayjs(date1).isBefore(date2); 41 | }; 42 | 43 | export const isAfter = ( 44 | date1: Date | string, 45 | date2: Date | string 46 | ): boolean => { 47 | return dayjs(date1).isAfter(date2); 48 | }; 49 | -------------------------------------------------------------------------------- /bitbit/src/store/slices/userSlice.ts: -------------------------------------------------------------------------------- 1 | import { createSlice, type PayloadAction } from "@reduxjs/toolkit"; 2 | import type { User } from "../../types"; 3 | 4 | interface UserState { 5 | currentUser: User | null; 6 | loading: boolean; 7 | error: string | null; 8 | } 9 | 10 | const initialState: UserState = { 11 | currentUser: null, 12 | loading: false, 13 | error: null, 14 | }; 15 | 16 | const userSlice = createSlice({ 17 | name: "user", 18 | initialState, 19 | reducers: { 20 | setUser: (state, action: PayloadAction) => { 21 | state.currentUser = action.payload; 22 | state.error = null; 23 | }, 24 | clearUser: (state) => { 25 | state.currentUser = null; 26 | }, 27 | updateUserStart: (state) => { 28 | state.loading = true; 29 | state.error = null; 30 | }, 31 | updateUserSuccess: (state, action: PayloadAction) => { 32 | state.currentUser = action.payload; 33 | state.loading = false; 34 | state.error = null; 35 | }, 36 | updateUserFailure: (state, action: PayloadAction) => { 37 | state.loading = false; 38 | state.error = action.payload; 39 | }, 40 | }, 41 | }); 42 | 43 | export const { 44 | setUser, 45 | clearUser, 46 | updateUserStart, 47 | updateUserSuccess, 48 | updateUserFailure, 49 | } = userSlice.actions; 50 | export const userReducer = userSlice.reducer; 51 | -------------------------------------------------------------------------------- /bitbit/src/App.css: -------------------------------------------------------------------------------- 1 | .app-container { 2 | display: flex; 3 | flex-direction: column; 4 | min-height: 100vh; 5 | padding-bottom: 72px; /* 为固定底部导航留出空间 */ 6 | } 7 | 8 | .app-header { 9 | position: sticky; 10 | top: 0; 11 | z-index: 100; 12 | background-color: #ffffff; 13 | height: 70px; 14 | display: flex; 15 | align-items: center; 16 | border-bottom: 1px solid rgba(0, 0, 0, 0.05); 17 | } 18 | 19 | .header-content { 20 | width: 100%; 21 | padding: 0 16px; 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | } 26 | 27 | .header-title { 28 | margin: 0; 29 | font-size: 18px; 30 | font-weight: 600; 31 | color: #222222; 32 | } 33 | 34 | .main-content { 35 | flex: 1; 36 | overflow-y: auto; 37 | width: 100%; 38 | } 39 | 40 | .bottom-nav { 41 | display: flex; 42 | justify-content: space-around; 43 | align-items: center; 44 | height: 56px; 45 | background-color: #ffffff; 46 | border-top: 1px solid #e0e0e6; 47 | position: fixed; 48 | bottom: 0; 49 | left: 0; 50 | right: 0; 51 | padding: 8px; 52 | box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05); 53 | } 54 | 55 | .bottom-nav a { 56 | color: #666666; 57 | text-decoration: none; 58 | display: flex; 59 | flex-direction: column; 60 | align-items: center; 61 | font-size: 12px; 62 | transition: color 0.25s ease; 63 | } 64 | 65 | .bottom-nav a.active { 66 | color: #4e6fff; 67 | } 68 | -------------------------------------------------------------------------------- /bitbit/src/features/activities/components/ActivityForm/DescriptionSection.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Card, CardContent } from "@/components/ui"; 3 | import type { ActivityFormData } from "../ActivityForm"; 4 | 5 | interface DescriptionSectionProps { 6 | formData: ActivityFormData; 7 | onFieldChange: ( 8 | field: K, 9 | value: ActivityFormData[K] 10 | ) => void; 11 | onFieldFocus: (fieldName: string) => void; 12 | } 13 | 14 | export const DescriptionSection: React.FC = ({ 15 | formData, 16 | onFieldChange, 17 | onFieldFocus, 18 | }) => { 19 | return ( 20 | 21 | 22 |
23 | 26 |