banxiang/lib/screens/profile_setup_screen.dart
2026-02-17 16:10:18 +08:00

196 lines
7.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import '../services/auth_service.dart';
import '../utils/constants.dart';
import 'activity_list_screen.dart';
class ProfileSetupScreen extends StatefulWidget {
const ProfileSetupScreen({super.key});
@override
State<ProfileSetupScreen> createState() => _ProfileSetupScreenState();
}
class _ProfileSetupScreenState extends State<ProfileSetupScreen> {
final _pageController = PageController();
int _currentStep = 0;
final _nicknameController = TextEditingController();
String? _gender;
int? _birthYear;
final Set<String> _selectedInterests = {};
void _nextStep() {
if (_currentStep < 2) {
setState(() => _currentStep++);
_pageController.animateToPage(_currentStep, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
} else {
_finishSetup();
}
}
void _finishSetup() async {
await AuthService.updateProfile(
nickname: _nicknameController.text.trim().isEmpty ? null : _nicknameController.text.trim(),
birthYear: _birthYear,
gender: _gender,
interests: _selectedInterests.toList(),
);
if (mounted) {
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => ActivityListScreen()));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('完善资料 (${_currentStep + 1}/3)'),
actions: [
TextButton(
onPressed: _finishSetup,
child: const Text('跳过', style: TextStyle(fontSize: 16)),
),
],
),
body: PageView(
controller: _pageController,
physics: const NeverScrollableScrollPhysics(),
children: [
// Step 1: Nickname
Padding(
padding: const EdgeInsets.all(32),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('给自己取个昵称吧', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
const Text('其他人将通过昵称认识您', style: TextStyle(fontSize: 16, color: Color(0xFF999999))),
const SizedBox(height: 32),
Center(
child: GestureDetector(
onTap: () {},
child: CircleAvatar(
radius: 50,
backgroundColor: const Color(0xFFE3F2FD),
child: const Icon(Icons.camera_alt, size: 32, color: Color(0xFF1976D2)),
),
),
),
const SizedBox(height: 8),
const Center(child: Text('点击设置头像', style: TextStyle(fontSize: 14, color: Color(0xFF999999)))),
const SizedBox(height: 24),
TextField(
controller: _nicknameController,
style: const TextStyle(fontSize: 20),
maxLength: 20,
decoration: const InputDecoration(hintText: '输入您的昵称', counterText: ''),
),
const Spacer(),
SizedBox(width: double.infinity, height: 52, child: ElevatedButton(onPressed: _nextStep, child: const Text('下一步'))),
],
),
),
// Step 2: Birth year + Gender
Padding(
padding: const EdgeInsets.all(32),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('基本信息', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 32),
const Text('性别', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
const SizedBox(height: 12),
Row(
children: [
Expanded(child: _genderButton('', 'male', Icons.male)),
const SizedBox(width: 16),
Expanded(child: _genderButton('', 'female', Icons.female)),
],
),
const SizedBox(height: 32),
const Text('出生年份', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600)),
const SizedBox(height: 12),
DropdownButtonFormField<int>(
value: _birthYear,
style: const TextStyle(fontSize: 18, color: Color(0xFF333333)),
decoration: const InputDecoration(hintText: '选择出生年份'),
items: List.generate(50, (i) => 1945 + i)
.map((y) => DropdownMenuItem(value: y, child: Text('$y年')))
.toList(),
onChanged: (v) => setState(() => _birthYear = v),
),
const Spacer(),
SizedBox(width: double.infinity, height: 52, child: ElevatedButton(onPressed: _nextStep, child: const Text('下一步'))),
],
),
),
// Step 3: Interests
Padding(
padding: const EdgeInsets.all(32),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('选择您的兴趣', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
const Text('至少选1个最多5个', style: TextStyle(fontSize: 16, color: Color(0xFF999999))),
const SizedBox(height: 24),
Wrap(
spacing: 12, runSpacing: 12,
children: AppConstants.interestTags.map((tag) {
final selected = _selectedInterests.contains(tag);
return ChoiceChip(
label: Text(tag, style: TextStyle(fontSize: 16, color: selected ? Colors.white : const Color(0xFF666666))),
selected: selected,
selectedColor: const Color(0xFF1976D2),
backgroundColor: const Color(0xFFF5F5F5),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
onSelected: (s) {
setState(() {
if (s && _selectedInterests.length < 5) {
_selectedInterests.add(tag);
} else {
_selectedInterests.remove(tag);
}
});
},
);
}).toList(),
),
const Spacer(),
SizedBox(
width: double.infinity, height: 52,
child: ElevatedButton(
onPressed: _selectedInterests.isNotEmpty ? _nextStep : null,
child: const Text('完成'),
),
),
],
),
),
],
),
);
}
Widget _genderButton(String label, String value, IconData icon) {
final selected = _gender == value;
return GestureDetector(
onTap: () => setState(() => _gender = value),
child: Container(
height: 64,
decoration: BoxDecoration(
color: selected ? const Color(0xFFE3F2FD) : Colors.white,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: selected ? const Color(0xFF1976D2) : const Color(0xFFDDDDDD), width: selected ? 2 : 1),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color: selected ? const Color(0xFF1976D2) : const Color(0xFF999999), size: 28),
const SizedBox(width: 8),
Text(label, style: TextStyle(fontSize: 18, color: selected ? const Color(0xFF1976D2) : const Color(0xFF666666), fontWeight: selected ? FontWeight.w600 : FontWeight.normal)),
],
),
),
);
}
}