| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- import 'package:flutter/material.dart';
- import 'package:intl/intl.dart';
- import 'package:japp_flutter/core/models/challenge_model.dart';
- class ChallengeCard extends StatelessWidget {
- final ChallengeModel challenge;
- const ChallengeCard({super.key, required this.challenge});
- @override
- Widget build(BuildContext context) {
- final theme = Theme.of(context);
- return Card(
- elevation: 2,
- shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
- margin: const EdgeInsets.only(bottom: 16),
- child: Padding(
- padding: const EdgeInsets.all(16),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- children: [
- Expanded(
- child: Text(
- challenge.title,
- style: const TextStyle(
- fontSize: 18,
- fontWeight: FontWeight.bold,
- ),
- ),
- ),
- _DifficultyChip(difficulty: challenge.difficulty),
- ],
- ),
- const SizedBox(height: 8),
- Text(
- challenge.description,
- style: TextStyle(color: Colors.grey[700], fontSize: 14),
- ),
- const SizedBox(height: 16),
- _ProgressBar(
- startDate: challenge.startDate,
- endDate: challenge.endDate,
- remainingDays: challenge.remainingDays?? 0,
- ),
- const SizedBox(height: 12),
- _CardFooter(
- participants: challenge.participants,
- remainingDays: challenge.remainingDays ?? 0,
- ),
- ],
- ),
- ),
- );
- }
- }
- // 将复杂子组件拆分为独立组件
- class _DifficultyChip extends StatelessWidget {
- final String difficulty;
- const _DifficultyChip({required this.difficulty});
- Color _getColor() {
- switch (difficulty) {
- case '简单':
- return Colors.green;
- case '中等':
- return Colors.orange;
- case '困难':
- return Colors.red;
- default:
- return Colors.grey;
- }
- }
- @override
- Widget build(BuildContext context) {
- return Chip(
- label: Text(difficulty, style: const TextStyle(color: Colors.white)),
- backgroundColor: _getColor(),
- );
- }
- }
- class _ProgressBar extends StatelessWidget {
- final DateTime startDate;
- final DateTime endDate;
- final int remainingDays;
- const _ProgressBar({
- required this.startDate,
- required this.endDate,
- required this.remainingDays,
- });
- @override
- Widget build(BuildContext context) {
- final theme = Theme.of(context);
- final totalDays = endDate.difference(startDate).inDays;
- final passedDays = totalDays - remainingDays;
- final progress = passedDays / totalDays;
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- '${(progress * 100).toStringAsFixed(0)}%',
- style: const TextStyle(fontSize: 12),
- ),
- const SizedBox(height: 4),
- LinearProgressIndicator(
- value: progress,
- backgroundColor: Colors.grey[200],
- borderRadius: BorderRadius.circular(10),
- minHeight: 8,
- color: theme.primaryColor,
- ),
- const SizedBox(height: 4),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- DateFormat('MM/dd').format(startDate),
- style: const TextStyle(fontSize: 12),
- ),
- Text(
- DateFormat('MM/dd').format(endDate),
- style: const TextStyle(fontSize: 12),
- ),
- ],
- ),
- ],
- );
- }
- }
- class _CardFooter extends StatelessWidget {
- final int participants;
- final int remainingDays;
- const _CardFooter({required this.participants, required this.remainingDays});
- @override
- Widget build(BuildContext context) {
- return Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- _InfoChip(icon: Icons.people, text: '$participants人参加'),
- _InfoChip(icon: Icons.calendar_today, text: '剩余${remainingDays}天'),
- ],
- );
- }
- }
- class _InfoChip extends StatelessWidget {
- final IconData icon;
- final String text;
- const _InfoChip({required this.icon, required this.text});
- @override
- Widget build(BuildContext context) {
- return Container(
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
- decoration: BoxDecoration(
- color: Colors.grey[100],
- borderRadius: BorderRadius.circular(20),
- ),
- child: Row(
- children: [
- Icon(icon, size: 16, color: Colors.grey[600]),
- const SizedBox(width: 4),
- Text(text, style: TextStyle(color: Colors.grey[700])),
- ],
- ),
- );
- }
- }
|