Просмотр исходного кода

🗑️ chore(mobile): 删除移动端用户相关组件和页面

- 删除AvatarUploader.tsx组件
- 删除MemberPage.tsx页面
- 清理用户头像上传和个人资料相关功能代码
yourname 7 месяцев назад
Родитель
Сommit
17d50cf930
2 измененных файлов с 0 добавлено и 284 удалено
  1. 0 134
      src/client/mobile/components/AvatarUploader.tsx
  2. 0 150
      src/client/mobile/pages/MemberPage.tsx

+ 0 - 134
src/client/mobile/components/AvatarUploader.tsx

@@ -1,134 +0,0 @@
-import React, { useState, useRef, ChangeEvent } from 'react';
-import { CameraIcon, PlusIcon, CheckIcon } from '@heroicons/react/24/outline';
-
-interface AvatarUploaderProps {
-  initialAvatar?: string;
-  onUpload?: (file: File) => void;
-}
-
-export const AvatarUploader: React.FC<AvatarUploaderProps> = ({ initialAvatar }) => {
-  const [isUploading, setIsUploading] = useState<boolean>(false);
-  const [preview, setPreview] = useState<string | null>(initialAvatar || null);
-  const [showControls, setShowControls] = useState<boolean>(false);
-  const [uploadSuccess, setUploadSuccess] = useState<boolean>(false);
-  const fileInputRef = useRef<HTMLInputElement>(null);
-
-  // 处理文件选择
-  const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
-    const file = e.target.files?.[0];
-    if (!file) return;
-
-    // 检查文件类型
-    if (!file.type.startsWith('image/')) {
-      alert('请选择图片文件');
-      return;
-    }
-
-    // 检查文件大小 (限制2MB)
-    if (file.size > 2 * 1024 * 1024) {
-      alert('图片大小不能超过2MB');
-      return;
-    }
-
-    // 显示预览
-    const reader = new FileReader();
-    reader.onload = (event) => {
-      setPreview(event.target?.result as string);
-      // 模拟上传过程
-      simulateUpload(file);
-    };
-    reader.readAsDataURL(file);
-
-    // 重置input值,以便可以重复选择同一文件
-    if (e.target) e.target.value = '';
-  };
-
-  // 模拟上传过程
-  const simulateUpload = (file: File) => {
-    setIsUploading(true);
-    setUploadSuccess(false);
-    
-    // 模拟1.5秒上传时间
-    setTimeout(() => {
-      setIsUploading(false);
-      setUploadSuccess(true);
-      
-      // 3秒后隐藏成功提示
-      setTimeout(() => {
-        setUploadSuccess(false);
-      }, 3000);
-    }, 1500);
-  };
-
-  // 触发文件选择对话框
-  const triggerFileSelect = () => {
-    fileInputRef.current?.click();
-  };
-
-  return (
-    <div 
-      className="relative group"
-      onMouseEnter={() => setShowControls(true)}
-      onMouseLeave={() => setShowControls(false)}
-    >
-      {/* 头像预览区域 */}
-      <div className="w-24 h-24 rounded-full bg-gray-200 flex items-center justify-center overflow-hidden border-2 border-white shadow-sm">
-        {preview ? (
-          <img 
-            src={preview} 
-            alt="用户头像" 
-            className="h-full w-full object-cover rounded-full transition-transform duration-300 group-hover:scale-105"
-          />
-        ) : (
-          <div className="text-center">
-            <CameraIcon className="h-12 w-12 text-gray-400 mx-auto" />
-            <span className="text-xs text-gray-500 mt-1 block">上传头像</span>
-          </div>
-        )}
-        
-        {/* 上传状态指示器 */}
-        {isUploading && (
-          <div className="absolute inset-0 bg-black bg-opacity-50 rounded-full flex items-center justify-center">
-            <div className="h-8 w-8 border-4 border-white border-t-transparent rounded-full animate-spin"></div>
-          </div>
-        )}
-        
-        {/* 上传成功指示器 */}
-        {uploadSuccess && (
-          <div className="absolute inset-0 bg-green-500 bg-opacity-70 rounded-full flex items-center justify-center">
-            <CheckIcon className="h-10 w-10 text-white" />
-          </div>
-        )}
-      </div>
-      
-      {/* 上传控制按钮 - 悬停时显示 */}
-      {(showControls && !isUploading && !uploadSuccess) && (
-        <div className="absolute -bottom-2 -right-2 bg-blue-600 rounded-full p-2 shadow-md cursor-pointer hover:bg-blue-700 transition-colors">
-          <PlusIcon
-            className="h-5 w-5 text-white" 
-            onClick={triggerFileSelect}
-            title="更换头像"
-          />
-        </div>
-      )}
-      
-      {/* 隐藏的文件输入 */}
-      <input
-        type="file"
-        ref={fileInputRef}
-        accept="image/*"
-        className="hidden"
-        onChange={handleFileChange}
-      />
-      
-      {/* 裁剪提示 */}
-      {(preview && !isUploading && !uploadSuccess) && (
-        <p className="text-xs text-gray-500 mt-2 text-center">
-          点击上传新头像 (建议尺寸: 200x200px)
-        </p>
-      )}
-    </div>
-  );
-};
-
-export default AvatarUploader;

+ 0 - 150
src/client/mobile/pages/MemberPage.tsx

@@ -1,150 +0,0 @@
-import debug from 'debug';
-import React from 'react';
-import { UserIcon, PencilIcon } from '@heroicons/react/24/outline';
-import AvatarUploader from '@/client/mobile/components/AvatarUploader';
-import { useParams, useNavigate } from 'react-router-dom';
-import { useQuery } from '@tanstack/react-query';
-import type { InferResponseType } from 'hono/client';
-import { userClient } from '@/client/api';
-import { useAuth, User } from '@/client/mobile/hooks/AuthProvider';
-import Footer from '@/client/mobile/components/Footer';
-
-const MemberPage: React.FC = () => {
-  const navigate = useNavigate();
-  const { user, logout } = useAuth();
-
-  if (!user) {
-    return (
-      <div className="text-center py-12">
-        <h2 className="text-2xl font-bold text-gray-900 mb-4">用户不存在</h2>
-        <button
-          onClick={() => navigate('/')}
-          className="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
-        >
-          返回首页
-        </button>
-      </div>
-    );
-  }
-
-  return (
-    <div className="min-h-screen bg-gray-50">
-      <div className="container mx-auto px-4 py-8 max-w-4xl">
-        {/* 用户资料卡片 */}
-        <div className="bg-white rounded-lg shadow-sm p-6 mb-8">
-          <div className="flex flex-col items-center">
-            <AvatarUploader initialAvatar={user.avatar} />
-            
-            <h1 className="text-2xl font-bold text-gray-900 mb-1">{user.nickname || user.username}</h1>
-            
-            <div className="flex space-x-8 my-4">
-              <div className="text-center">
-                <p className="text-2xl font-semibold text-gray-900">0</p>
-                <p className="text-sm text-gray-500">内容</p>
-              </div>
-              <div className="text-center">
-                <p className="text-2xl font-semibold text-gray-900">0</p>
-                <p className="text-sm text-gray-500">关注</p>
-              </div>
-              <div className="text-center">
-                <p className="text-2xl font-semibold text-gray-900">0</p>
-                <p className="text-sm text-gray-500">粉丝</p>
-              </div>
-            </div>
-            
-            <div className="flex">
-              <button
-                onClick={() => navigate('/profile/edit')}
-                className="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 flex items-center"
-              >
-                <PencilIcon className="w-4 h-4 mr-2" />
-                编辑资料
-              </button>
-              
-              <button
-                onClick={async () => {
-                  await logout();
-                  navigate('/');
-                }}
-                className="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 ml-4"
-              >
-                退出登录
-              </button>
-
-            </div>
-            
-            {(user as any).bio && (
-              <p className="mt-4 text-center text-gray-600 max-w-lg">
-                {(user as any).bio}
-              </p>
-            )}
-            
-            <div className="flex items-center mt-4 space-x-4">
-              {(user as any).location && (
-                <div className="flex items-center text-gray-600">
-                  <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
-                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
-                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
-                  </svg>
-                  <span className="text-sm">{(user as any).location}</span>
-                </div>
-              )}
-              {(user as any).website && (
-                <a
-                  href={(user as any).website}
-                  target="_blank"
-                  rel="noopener noreferrer"
-                  className="flex items-center text-blue-600 hover:text-blue-800"
-                >
-                  <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
-                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6v6m0 0v6m0-6h-6" />
-                  </svg>
-                  <span className="text-sm truncate max-w-[150px]">{(user as any).website}</span>
-                </a>
-              )}
-            </div>
-          </div>
-        </div>
-        
-        {/* 用户内容区域 */}
-        <div className="bg-white rounded-lg shadow-sm p-6">
-          <h2 className="text-xl font-semibold mb-6">个人资料</h2>
-          
-          <div className="space-y-4">
-            <div className="border-b border-gray-100 pb-4">
-              <h3 className="text-sm font-medium text-gray-500 mb-1">用户名</h3>
-              <p className="text-gray-900">{user.username}</p>
-            </div>
-            
-            <div className="border-b border-gray-100 pb-4">
-              <h3 className="text-sm font-medium text-gray-500 mb-1">电子邮箱</h3>
-              <p className="text-gray-900">{user.email || '未设置'}</p>
-            </div>
-            
-            <div className="border-b border-gray-100 pb-4">
-              <h3 className="text-sm font-medium text-gray-500 mb-1">注册时间</h3>
-              <p className="text-gray-900">{user.createdAt ? new Date(user.createdAt).toLocaleDateString() : '未知'}</p>
-            </div>
-            
-            <div className="border-b border-gray-100 pb-4">
-              <h3 className="text-sm font-medium text-gray-500 mb-1">最后登录</h3>
-              <p className="text-gray-900">{user.updatedAt ? new Date(user.updatedAt).toLocaleString() : '从未登录'}</p>
-            </div>
-          </div>
-          
-          <div className="mt-8">
-            <button
-              onClick={() => navigate('/profile/security')}
-              className="w-full py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
-            >
-              安全设置
-            </button>
-          </div>
-        </div>
-      </div>
-      <Footer />
-    </div>
-  );
-};
-
-export default MemberPage;