# Cambridge EduX Hackathon 2025 管理平台

## 📋 项目简介

这是一个为 Cambridge EduX Hackathon 2025 设计的完整管理平台，包含：

- ✅ **公开展示页**：面向参赛者的只读展示界面，显示 Challenge 列表、队伍信息、倒计时等
- ✅ **管理员后台**：数据导入、Challenge 管理、队伍管理、同步设置等
- ✅ **数据同步**：支持 CSV/Excel 导入、Google Sheet 同步、Webhook 推送
- ✅ **响应式设计**：完美支持移动端和桌面端
- ✅ **Supabase 集成**：使用 Supabase 作为后端数据库

## 🗂 文件结构

```
├── hackathon-2025.html          # 公开展示页（参赛者访问）
├── hackathon-admin.html         # 管理员后台
├── hackathon-config.js          # 配置文件模板
├── hackathon-setup.sql          # 数据库表结构 SQL
└── README-HACKATHON.md          # 本文档
```

## 🚀 快速开始

### 第一步：设置 Supabase 数据库

1. **创建 Supabase 项目**
   - 访问 [https://supabase.com](https://supabase.com)
   - 点击 "New Project" 创建新项目
   - 记录项目的 URL 和 API Key

2. **创建数据库表**
   - 进入 Supabase Dashboard → SQL Editor
   - 复制 `hackathon-setup.sql` 中的所有内容
   - 粘贴并运行 SQL 语句
   - 确认所有表都已成功创建

3. **验证表结构**
   ```sql
   SELECT table_name FROM information_schema.tables 
   WHERE table_schema = 'public' 
   ORDER BY table_name;
   ```
   应该看到：`challenges`, `teams`, `team_members`, `announcements`, `sync_logs`, `settings`, `admin_users`

### 第二步：配置项目

1. **创建配置文件**
   ```bash
   # 复制配置模板
   cp hackathon-config.js hackathon-config.local.js
   ```

2. **编辑 `hackathon-config.local.js`**
   ```javascript
   const HACKATHON_CONFIG = {
       SUPABASE: {
           URL: 'https://xxxxx.supabase.co',  // 你的 Supabase URL
           ANON_KEY: 'eyJhbGc...',             // 你的 Supabase Anon Key
       },
       
       EVENT: {
           NAME: 'Cambridge EduX Hackathon 2025',
           DEADLINE: '2025-03-15T23:59:59',
       },
       
       LINKS: {
           SUBMISSION: 'https://forms.gle/your-submission',
           SCHEDULE: 'https://docs.google.com/your-schedule',
           GROUP_CHAT: 'https://chat.whatsapp.com/your-group',
       },
       
       // ... 其他配置
   };
   ```

3. **添加到 .gitignore**
   ```
   hackathon-config.local.js
   ```

### 第三步：引入 Supabase JS 库

在 `hackathon-2025.html` 和 `hackathon-admin.html` 的 `<head>` 标签中添加：

```html
<!-- Supabase JS -->
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>

<!-- 配置文件 -->
<script src="hackathon-config.local.js"></script>
```

### 第四步：更新 JavaScript 初始化代码

在两个 HTML 文件的 `<script>` 标签中，更新配置：

```javascript
// hackathon-2025.html
const CONFIG = window.HACKATHON_CONFIG || {
    SUPABASE_URL: 'YOUR_SUPABASE_URL',
    SUPABASE_ANON_KEY: 'YOUR_SUPABASE_ANON_KEY',
    // ...
};

// 初始化 Supabase
const supabase = window.supabase.createClient(
    CONFIG.SUPABASE.URL, 
    CONFIG.SUPABASE.ANON_KEY
);
```

### 第五步：本地测试

1. **启动本地服务器**
   ```bash
   # 使用 Python
   python -m http.server 8000
   
   # 或使用 Node.js
   npx http-server -p 8000
   
   # 或使用 VS Code Live Server 插件
   ```

2. **访问页面**
   - 公开展示页：`http://localhost:8000/hackathon-2025.html`
   - 管理后台：`http://localhost:8000/hackathon-admin.html`

3. **测试功能**
   - 登录管理后台（首次使用可以用任意邮箱密码）
   - 创建几个 Challenge
   - 查看公开页是否正常显示
   - 测试数据导入功能

### 第六步：部署到生产环境

#### 选项 A：Netlify（推荐）

1. 在项目根目录创建 `netlify.toml`：
   ```toml
   [build]
     publish = "."
   
   [[redirects]]
     from = "/*"
     to = "/hackathon-2025.html"
     status = 200
   ```

2. 部署步骤：
   - 访问 [https://netlify.com](https://netlify.com)
   - 连接 GitHub 仓库或拖拽文件夹上传
   - 配置环境变量（如果需要）
   - 部署完成后获取域名

#### 选项 B：Vercel

1. 安装 Vercel CLI：
   ```bash
   npm install -g vercel
   ```

2. 部署：
   ```bash
   vercel
   ```

#### 选项 C：GitHub Pages

1. 在 GitHub 仓库设置中启用 Pages
2. 选择分支和目录
3. 访问 `https://yourusername.github.io/repo-name/hackathon-2025.html`

**注意**：无论哪种部署方式，都要确保：
- ✅ `hackathon-config.local.js` 已正确配置
- ✅ `hackathon-config.local.js` 不要上传到公开仓库
- ✅ Supabase RLS 策略已正确配置

## 📖 功能使用指南

### 1. 管理员后台使用

#### 登录
- 访问 `hackathon-admin.html`
- 输入邮箱和密码登录
- 首次使用时，可以用任意邮箱密码（需要配置 Supabase Auth）

#### 创建 Challenge
1. 点击左侧导航 "Challenges"
2. 点击 "+ 创建 Challenge"
3. 填写信息：
   - Challenge 名称（必填）
   - 描述
   - 总容量（必填）
   - 最小/最大队伍人数
   - 状态（开放/已满/候补/关闭）
4. 勾选"立即发布到公开页"
5. 点击"创建"

#### 导入 CSV 数据
1. 点击左侧导航 "数据导入"
2. 准备 CSV 文件，必需字段：
   ```csv
   challenge_name,team_name,member_count,status
   AI 驱动的个性化学习,AI Learners,4,confirmed
   VR/AR 沉浸式教育,VR Innovators,5,confirmed
   ```
3. 拖拽或点击上传文件
4. 预览数据
5. 点击"确认导入"

#### Google Sheet 同步
1. 点击左侧导航 "同步设置"
2. 填写 Google Sheet URL
3. 粘贴 Service Account JSON 或 API Key
4. 勾选"启用自动同步"
5. 点击"保存设置"
6. 点击"立即同步"测试

#### 队伍管理
1. 点击左侧导航 "队伍管理"
2. 查看所有已报名队伍
3. 可以筛选特定 Challenge
4. 编辑或删除队伍
5. 调整队伍状态（确认/候补/拒绝）

#### 公告管理
1. 点击左侧导航 "公告管理"
2. 点击 "+ 新建公告"
3. 填写标题、内容、类型
4. 选择目标 Challenge（可选）
5. 保存后自动显示在公开页

#### 数据导出
1. 点击顶部"概览"
2. 点击"导出数据"
3. 下载 CSV 文件，包含所有队伍和 Challenge 信息

### 2. 公开展示页使用

参赛者访问 `hackathon-2025.html` 可以：

- ✅ 查看所有已发布的 Challenge
- ✅ 查看每个 Challenge 的剩余名额
- ✅ 查看已报名的队伍列表
- ✅ 查看提交截止倒计时
- ✅ 访问提交入口、日程、交流群等外部链接
- ✅ 点击"报名参加"跳转到外部表单

### 3. 数据同步流程

#### CSV/Excel 导入
```
XLForm 导出 CSV
   ↓
上传到管理后台
   ↓
预览数据
   ↓
确认导入
   ↓
自动匹配 Challenge
   ↓
更新数据库
   ↓
公开页自动刷新
```

#### Google Sheet 同步
```
表单提交 → Google Sheet
   ↓
每10分钟自动同步（或手动同步）
   ↓
读取 Sheet 数据
   ↓
比对数据库
   ↓
插入新记录/更新已有记录
   ↓
公开页自动刷新
```

#### Webhook 推送（可选）
```
表单提交
   ↓
触发 Webhook
   ↓
推送到平台 API
   ↓
验证数据
   ↓
实时更新数据库
   ↓
公开页立即刷新
```

## 🔧 高级配置

### 配置 Google Sheet 同步

1. **创建 Google Service Account**
   - 访问 [Google Cloud Console](https://console.cloud.google.com)
   - 创建新项目或选择现有项目
   - 启用 Google Sheets API
   - 创建 Service Account
   - 生成 JSON Key

2. **配置 Sheet 权限**
   - 打开你的 Google Sheet
   - 点击"共享"
   - 添加 Service Account 的邮箱（xxx@xxx.iam.gserviceaccount.com）
   - 授予"查看者"或"编辑者"权限

3. **配置同步设置**
   - 在管理后台 → 同步设置
   - 粘贴 Sheet URL
   - 粘贴 Service Account JSON
   - 启用自动同步

### 配置 Webhook

1. **设置后端 API**
   创建一个接收 Webhook 的端点，例如：
   ```javascript
   // Supabase Edge Function 或 Vercel Serverless Function
   export default async function handler(req, res) {
       // 验证 Webhook 签名
       const signature = req.headers['x-webhook-signature'];
       // ...验证逻辑...
       
       // 解析数据
       const data = req.body;
       
       // 插入到 Supabase
       const { error } = await supabase
           .from('teams')
           .insert(data);
       
       res.status(200).json({ success: true });
   }
   ```

2. **配置表单 Webhook**
   - 在 XLForm 或其他表单平台配置 Webhook URL
   - 设置触发条件（提交时）
   - 配置认证方式（Secret Key）

### 自定义样式主题

在 `hackathon-config.local.js` 中修改：

```javascript
THEME: {
    PRIMARY_COLOR: '#0066cc',      // 主色调
    SECONDARY_COLOR: '#00a3e0',    // 次要色
    SUCCESS_COLOR: '#10b981',      // 成功状态
    WARNING_COLOR: '#f59e0b',      // 警告状态
    DANGER_COLOR: '#ef4444',       // 危险状态
}
```

或直接在 HTML 文件的 CSS `:root` 中修改：

```css
:root {
    --primary-color: #0066cc;
    --secondary-color: #00a3e0;
    /* ... */
}
```

## 📅 发布时间线（11/21 公布对齐）

### T-3 天（11/18）
- ✅ 导入历史报名数据
- ✅ 创建所有 Challenge
- ✅ 设置容量和限制
- ✅ 生成公开页但设置为"仅持链接可见"
- ✅ 内部测试

### 11/21 公布日
- ✅ 切换公开页为"公开访问"
- ✅ 群发链接给参赛者
- ✅ 打开外部组队表单
- ✅ 启用自动同步（每10分钟）

### 同步期间
- ✅ 自动同步报名数据
- ✅ 自动计算剩余名额
- ✅ 超额自动转为候补
- ✅ 实时更新公开页

### 提交期
- ✅ 公开页顶部显示"提交入口 + DDL 倒计时"
- ✅ 发布重要公告
- ✅ 必要时锁定某些 Challenge

## 🛠 故障排查

### 问题 1：数据无法加载
**症状**：公开页或管理后台显示"加载失败"

**解决方法**：
1. 检查浏览器控制台错误信息
2. 确认 Supabase URL 和 Key 配置正确
3. 检查 Supabase RLS 策略是否正确
4. 测试 Supabase 连接：管理后台 → 设置 → 测试连接

### 问题 2：无法创建 Challenge
**症状**：点击"创建"后没有反应或报错

**解决方法**：
1. 检查所有必填字段是否已填写
2. 确认容量 > 0
3. 确认 min_team_size ≤ max_team_size
4. 检查数据库表是否正确创建
5. 查看浏览器控制台错误

### 问题 3：CSV 导入失败
**症状**：CSV 文件无法识别或导入后数据不正确

**解决方法**：
1. 确认 CSV 格式正确（UTF-8 编码，逗号分隔）
2. 检查必需字段：`challenge_name`, `team_name`, `member_count`
3. 确认 challenge_name 与数据库中的 Challenge 名称完全匹配
4. 尝试手动创建一个队伍测试

### 问题 4：Google Sheet 同步不工作
**症状**：点击"立即同步"无反应或报错

**解决方法**：
1. 确认 Service Account JSON 格式正确
2. 确认 Service Account 已添加到 Sheet 的共享权限
3. 确认 Sheet URL 正确
4. 检查 Google Sheets API 是否已启用
5. 查看同步日志（管理后台 → 同步设置 → 同步历史）

### 问题 5：倒计时不显示或不准确
**症状**：倒计时显示"00:00:00:00"或错误时间

**解决方法**：
1. 检查 `DEADLINE` 配置格式：`2025-03-15T23:59:59`
2. 确认时区设置正确
3. 检查本地设备时间是否准确
4. 刷新浏览器缓存

## 📊 数据库表结构说明

### challenges 表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| name | VARCHAR | Challenge 名称 |
| description | TEXT | 描述 |
| capacity | INTEGER | 总容量 |
| filled | INTEGER | 已报名人数（自动计算）|
| min_team_size | INTEGER | 最小队伍人数 |
| max_team_size | INTEGER | 最大队伍人数 |
| status | VARCHAR | 状态：open/full/waitlist/closed |
| is_published | BOOLEAN | 是否发布 |
| created_at | TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 更新时间 |

### teams 表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| challenge_id | BIGINT | 关联的 Challenge |
| name | VARCHAR | 队伍名称 |
| member_count | INTEGER | 队伍人数 |
| status | VARCHAR | 状态：pending/confirmed/waitlist/rejected |
| tags | TEXT[] | 标签数组 |
| contact_email | VARCHAR | 联系邮箱 |
| created_at | TIMESTAMP | 创建时间 |

### team_members 表
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGSERIAL | 主键 |
| team_id | BIGINT | 关联的队伍 |
| name | VARCHAR | 成员姓名 |
| email | VARCHAR | 邮箱 |
| role | VARCHAR | 角色：leader/member/mentor |
| university | VARCHAR | 大学 |
| major | VARCHAR | 专业 |
| skills | TEXT[] | 技能标签 |

### 其他表
- `announcements`：公告
- `sync_logs`：同步日志
- `settings`：系统设置
- `admin_users`：管理员账户

## 🔒 安全建议

1. **保护配置文件**
   - ✅ 将 `hackathon-config.local.js` 添加到 `.gitignore`
   - ✅ 不要在公开仓库中提交敏感信息
   - ✅ 使用环境变量存储密钥

2. **Supabase RLS 策略**
   - ✅ 确保 RLS 已启用
   - ✅ 公开页只能读取 `is_published = true` 的 Challenge
   - ✅ 队员详细信息（`team_members`）仅管理员可访问

3. **管理员认证**
   - ✅ 配置 Supabase Auth
   - ✅ 使用强密码
   - ✅ 启用 2FA（可选）

4. **数据验证**
   - ✅ 后端验证所有输入数据
   - ✅ 防止 SQL 注入（使用参数化查询）
   - ✅ 限制上传文件大小和类型

## 📞 技术支持

如有问题或需要帮助，请：

- 📧 邮箱：support@cets.org
- 💬 微信群：扫描二维码加入
- 📝 GitHub Issues：[提交问题](https://github.com/your-repo/issues)

## 📝 更新日志

### v1.0.0 (2025-01-XX)
- ✅ 初始版本发布
- ✅ 公开展示页
- ✅ 管理员后台
- ✅ CSV 导入功能
- ✅ Google Sheet 同步（基础版）
- ✅ Supabase 集成

### 未来计划
- [ ] Webhook 实时推送
- [ ] 邮件通知功能
- [ ] 数据分析仪表板
- [ ] 队伍评分系统
- [ ] 多语言支持

## 📄 许可证

MIT License - 可自由使用和修改

---

**祝 Cambridge EduX Hackathon 2025 圆满成功！🎉**

