// // export default NewbieTasks;
// import React, { useEffect, useState } from 'react';
// import axios from 'axios';

// const NewbieTasks = () => {
//   const [tasks, setTasks] = useState([]);
//   const [experience, setExperience] = useState({});
//   const [currentStep, setCurrentStep] = useState({});
//   const [loading, setLoading] = useState(true);

//   const baseURL = '/echo/task/tutorial';
//   const userId = 1;

//   const fetchTasks = async () => {
//     try {
//       const response = await axios.get(`${baseURL}/getAllTasks`, {
//         params: { user_id: userId },
//       });
//       setTasks(response.data.tasks || []);
//     } catch (error) {
//       console.error('获取任务失败:', error);
//     }
//   };

//   const fetchExperience = async () => {
//     try {
//       const response = await axios.get(`${baseURL}/getAllTasks`, {
//         params: { user_id: userId },
//       });
//       setExperience(response.data || {});
//     } catch (error) {
//       console.error('获取经验失败:', error);
//     }
//   };

//   const fetchCurrentStep = async () => {
//     try {
//       const response = await axios.get(`${baseURL}/getNewStep`, {
//         params: { user_id: userId },
//       });
//       setCurrentStep(response.data || {});
//     } catch (error) {
//       console.error('获取引导步骤失败:', error);
//     }
//   };

//   const updateStatus = async (taskId) => {
//     try {
//       await axios.post(`${baseURL}/updateStatus`, {
//         user_id: userId,
//         task_id: taskId,
//       });
//       await fetchTasks();
//       await fetchExperience();
//     } catch (error) {
//       console.error('更新状态失败:', error);
//     }
//   };

//   const updateProgress = async (taskId, progress) => {
//     try {
//       await axios.post(`${baseURL}/updateProgress`, {
//         user_id: userId,
//         task_id: taskId,
//         progress,
//       });
//       await fetchTasks();
//     } catch (error) {
//       console.error('更新进度失败:', error);
//     }
//   };

//   const claimReward = async (taskId) => {
//     try {
//       await axios.post(`${baseURL}/rewardClaim`, {
//         user_id: userId,
//         task_id: taskId,
//       });
//       await fetchTasks();
//       await fetchExperience();
//     } catch (error) {
//       console.error('领取奖励失败:', error);
//     }
//   };

//   const checkRewardStatus = async (taskId) => {
//     try {
//       const response = await axios.post(`${baseURL}/rewardReview`, {
//         user_id: userId,
//         task_id: taskId,
//       });
//       alert(response.data.message || '已完成');
//     } catch (error) {
//       console.error('查看失败:', error);
//     }
//   };

//   useEffect(() => {
//     const init = async () => {
//       await fetchTasks();
//       await fetchExperience();
//       await fetchCurrentStep();
//       setLoading(false);
//     };
//     init();
//   }, []);

//   if (loading) return <p className="loading">加载中...</p>;

//   return (
//     <div className="common-card right-content">
//       <div className="profile-header">
//         <h1>🎯 用户等级</h1>
//       </div>

//       <div className="profile-details">
//         <p><strong>当前经验：</strong>{experience.current_experience}</p>
//         <p><strong>等级：</strong>{experience.level}</p>
//         <p><strong>奖励经验：</strong>{experience.reward?.experience || 0}</p>
//         <p><strong>奖励积分：</strong>{experience.reward?.points || 0}</p>
//       </div>

//       <div className="profile-details">
//         <p><strong>🧭 当前引导步骤：</strong>{currentStep.current_step}</p>
//         <p>{currentStep.step_description}</p>
//       </div>

//       <div className="profile-details">
//         <h2>任务列表</h2>
//         <ul>
//           {tasks.map(task => (
//             <li key={task.task_id} style={{ marginBottom: '20px', borderBottom: '1px solid #eee', paddingBottom: '10px' }}>
//               <p><strong>任务：</strong>{task.title}</p>
//               <p><strong>描述：</strong>{task.description}</p>
//               <p><strong>进度：</strong>{task.progress}%</p>
//               <p><strong>状态：</strong>{task.status}</p>
//               <p><strong>奖励：</strong>经验 {task.reward.experience}，积分 {task.reward.points}</p>

//               <div className="task-btn-group">
//                 <button className="task-btn" onClick={() => updateStatus(task.task_id)}>更新状态</button>
//                 <button className="task-btn" onClick={() => updateProgress(task.task_id, 100)}>提交进度</button>
//                 <button className="task-btn" onClick={() => claimReward(task.task_id)}>领取奖励</button>
//                 <button className="task-btn" onClick={() => checkRewardStatus(task.task_id)}>查看奖励状态</button>
//               </div>
//             </li>
//           ))}
//         </ul>
//       </div>
//     </div>
//   );
// };

// export default NewbieTasks;


import React from'react';
import './NewbieTasks.css'; 

const NewbieTasks = () => {
    const tableData = [
        {
            level: 'lv0【糖果】',
            newPermissions: '查看种子分类和评论，查看其他用户主页',
            upgradeConditions: '无'
        },
        {
            level: 'lv1【曲奇】',
            newPermissions: '上传免费种子，下载免费种子，发布评论，私信/关注其他用户，收藏种子',
            upgradeConditions: '经验≥50，分享率≥0.5，上传量≥10G，做种时长≥72h'
        },
        {
            level: 'lv2【巧克力】',
            newPermissions: '下载付费种子，成立和加入兴趣小组',
            upgradeConditions: '经验≥200，分享率≥0.75，上传量≥50G，做种时长≥240h'
        },
        {
            level: 'lv3【冰激凌】',
            newPermissions: '上传付费种子',
            upgradeConditions: '经验≥500，分享率≥1，上传量≥100G，做种时长≥600h'
        }
    ];
    return (
        <div className="newbie-tasks-container">
            <h2 className="page-title">🎯 用户等级</h2>
            <p>各个等级的权限在下面啦~ 经验值可以通过上传种子获得哦！</p>
            <table className="tasks-table">
                <thead>
                    <tr>
                        <th>用户等级</th>
                        <th>新增权限</th>
                        <th>升级条件</th>
                    </tr>
                </thead>
                <tbody>
                    {tableData.map((item, index) => (
                        <tr key={index}>
                            <td>{item.level}</td>
                            <td>{item.newPermissions}</td>
                            <td>{item.upgradeConditions}</td>
                        </tr>
                    ))}
                </tbody>
            </table>
        </div>
    );
};

export default NewbieTasks;
