335 lines
8.7 KiB
Dart
335 lines
8.7 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
|
|
/// Model para definição de conquistas
|
|
class Achievement {
|
|
final String id;
|
|
final String name;
|
|
final String description;
|
|
final String icon;
|
|
final String category; // 'streak', 'study_time', 'quiz', 'concept'
|
|
final AchievementRequirement requirements;
|
|
final int points;
|
|
final String rarity; // 'common', 'rare', 'epic', 'legendary'
|
|
final bool isActive;
|
|
final DateTime createdAt;
|
|
final String? createdBy; // teacherId se criada por professor
|
|
|
|
const Achievement({
|
|
required this.id,
|
|
required this.name,
|
|
required this.description,
|
|
required this.icon,
|
|
required this.category,
|
|
required this.requirements,
|
|
required this.points,
|
|
required this.rarity,
|
|
required this.isActive,
|
|
required this.createdAt,
|
|
this.createdBy,
|
|
});
|
|
|
|
factory Achievement.fromFirestore(Map<String, dynamic> data, String id) {
|
|
return Achievement(
|
|
id: id,
|
|
name: data['name'] ?? '',
|
|
description: data['description'] ?? '',
|
|
icon: data['icon'] ?? 'star',
|
|
category: data['category'] ?? 'general',
|
|
requirements: AchievementRequirement.fromFirestore(data['requirements'] ?? {}),
|
|
points: data['points'] ?? 0,
|
|
rarity: data['rarity'] ?? 'common',
|
|
isActive: data['isActive'] ?? true,
|
|
createdAt: (data['createdAt'] as Timestamp?)?.toDate() ?? DateTime.now(),
|
|
createdBy: data['createdBy'],
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toFirestore() {
|
|
return {
|
|
'name': name,
|
|
'description': description,
|
|
'icon': icon,
|
|
'category': category,
|
|
'requirements': requirements.toFirestore(),
|
|
'points': points,
|
|
'rarity': rarity,
|
|
'isActive': isActive,
|
|
'createdAt': Timestamp.fromDate(createdAt),
|
|
if (createdBy != null) 'createdBy': createdBy,
|
|
};
|
|
}
|
|
|
|
Achievement copyWith({
|
|
String? id,
|
|
String? name,
|
|
String? description,
|
|
String? icon,
|
|
String? category,
|
|
AchievementRequirement? requirements,
|
|
int? points,
|
|
String? rarity,
|
|
bool? isActive,
|
|
String? createdBy,
|
|
}) {
|
|
return Achievement(
|
|
id: id ?? this.id,
|
|
name: name ?? this.name,
|
|
description: description ?? this.description,
|
|
icon: icon ?? this.icon,
|
|
category: category ?? this.category,
|
|
requirements: requirements ?? this.requirements,
|
|
points: points ?? this.points,
|
|
rarity: rarity ?? this.rarity,
|
|
isActive: isActive ?? this.isActive,
|
|
createdAt: createdAt,
|
|
createdBy: createdBy ?? this.createdBy,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Requisitos para desbloquear uma conquista
|
|
class AchievementRequirement {
|
|
final String type; // 'streak_days', 'study_time', 'quiz_score', 'concepts_mastered', 'quiz_completion'
|
|
final num value;
|
|
final String operator; // '>=', '==', '>'
|
|
final Map<String, dynamic>? additionalParams;
|
|
|
|
const AchievementRequirement({
|
|
required this.type,
|
|
required this.value,
|
|
required this.operator,
|
|
this.additionalParams,
|
|
});
|
|
|
|
factory AchievementRequirement.fromFirestore(Map<String, dynamic> data) {
|
|
return AchievementRequirement(
|
|
type: data['type'] ?? '',
|
|
value: data['value'] ?? 0,
|
|
operator: data['operator'] ?? '>=',
|
|
additionalParams: data['additionalParams'],
|
|
);
|
|
}
|
|
|
|
Map<String, dynamic> toFirestore() {
|
|
return {
|
|
'type': type,
|
|
'value': value,
|
|
'operator': operator,
|
|
if (additionalParams != null) 'additionalParams': additionalParams,
|
|
};
|
|
}
|
|
|
|
bool checkCondition(num currentValue) {
|
|
switch (operator) {
|
|
case '>=':
|
|
return currentValue >= value;
|
|
case '==':
|
|
return currentValue == value;
|
|
case '>':
|
|
return currentValue > value;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Conquistas predefinidas do sistema
|
|
class SystemAchievements {
|
|
static List<Achievement> get defaultAchievements => [
|
|
Achievement(
|
|
id: 'first_quiz',
|
|
name: 'Primeiro Passo',
|
|
description: 'Complete seu primeiro quiz',
|
|
icon: 'emoji_events',
|
|
category: 'quiz',
|
|
requirements: AchievementRequirement(
|
|
type: 'quiz_completion',
|
|
value: 1,
|
|
operator: '>=',
|
|
),
|
|
points: 10,
|
|
rarity: 'common',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'week_streak',
|
|
name: 'Semana de Dedicação',
|
|
description: 'Mantenha uma streak de 7 dias',
|
|
icon: 'local_fire_department',
|
|
category: 'streak',
|
|
requirements: AchievementRequirement(
|
|
type: 'streak_days',
|
|
value: 7,
|
|
operator: '>=',
|
|
),
|
|
points: 50,
|
|
rarity: 'rare',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'study_marathon',
|
|
name: 'Maratona de Estudos',
|
|
description: 'Estude por 100 minutos em um dia',
|
|
icon: 'schedule',
|
|
category: 'study_time',
|
|
requirements: AchievementRequirement(
|
|
type: 'study_time',
|
|
value: 100,
|
|
operator: '>=',
|
|
additionalParams: {'period': 'daily'},
|
|
),
|
|
points: 30,
|
|
rarity: 'rare',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'first_quiz',
|
|
name: 'Primeiro Passo',
|
|
description: 'Complete seu primeiro quiz',
|
|
icon: 'emoji_events',
|
|
category: 'quiz',
|
|
requirements: AchievementRequirement(
|
|
type: 'quiz_completion',
|
|
value: 1,
|
|
operator: '>=',
|
|
),
|
|
points: 10,
|
|
rarity: 'common',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'perfect_score',
|
|
name: 'Perfeição',
|
|
description: 'Obtenha 100% em um quiz',
|
|
icon: 'star',
|
|
category: 'quiz',
|
|
requirements: AchievementRequirement(
|
|
type: 'quiz_score',
|
|
value: 100,
|
|
operator: '==',
|
|
),
|
|
points: 25,
|
|
rarity: 'rare',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'concept_master',
|
|
name: 'Mestre de Conceitos',
|
|
description: 'Domine 5 conceitos',
|
|
icon: 'school',
|
|
category: 'concept',
|
|
requirements: AchievementRequirement(
|
|
type: 'concepts_mastered',
|
|
value: 5,
|
|
operator: '>=',
|
|
),
|
|
points: 40,
|
|
rarity: 'epic',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'month_streak',
|
|
name: 'Lendário',
|
|
description: 'Mantenha uma streak de 30 dias',
|
|
icon: 'whatshot',
|
|
category: 'streak',
|
|
requirements: AchievementRequirement(
|
|
type: 'streak_days',
|
|
value: 30,
|
|
operator: '>=',
|
|
),
|
|
points: 200,
|
|
rarity: 'legendary',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
// Conquistas genéricas de número de quizzes
|
|
Achievement(
|
|
id: 'quiz_novice_5',
|
|
name: 'Iniciante',
|
|
description: 'Complete 5 quizzes',
|
|
icon: 'emoji_events',
|
|
category: 'quiz_count',
|
|
requirements: AchievementRequirement(
|
|
type: 'quiz_completion',
|
|
value: 5,
|
|
operator: '>=',
|
|
),
|
|
points: 15,
|
|
rarity: 'common',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'quiz_intermediate_10',
|
|
name: 'Estudante Dedicao',
|
|
description: 'Complete 10 quizzes',
|
|
icon: 'school',
|
|
category: 'quiz_count',
|
|
requirements: AchievementRequirement(
|
|
type: 'quiz_completion',
|
|
value: 10,
|
|
operator: '>=',
|
|
),
|
|
points: 30,
|
|
rarity: 'common',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'quiz_advanced_25',
|
|
name: 'Mestre dos Quizzes',
|
|
description: 'Complete 25 quizzes',
|
|
icon: 'military_tech',
|
|
category: 'quiz_count',
|
|
requirements: AchievementRequirement(
|
|
type: 'quiz_completion',
|
|
value: 25,
|
|
operator: '>=',
|
|
),
|
|
points: 75,
|
|
rarity: 'rare',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'quiz_expert_50',
|
|
name: 'Especialista',
|
|
description: 'Complete 50 quizzes',
|
|
icon: 'workspace_premium',
|
|
category: 'quiz_count',
|
|
requirements: AchievementRequirement(
|
|
type: 'quiz_completion',
|
|
value: 50,
|
|
operator: '>=',
|
|
),
|
|
points: 150,
|
|
rarity: 'epic',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
Achievement(
|
|
id: 'quiz_legend_100',
|
|
name: 'Lenda dos Quizzes',
|
|
description: 'Complete 100 quizzes',
|
|
icon: 'stars',
|
|
category: 'quiz_count',
|
|
requirements: AchievementRequirement(
|
|
type: 'quiz_completion',
|
|
value: 100,
|
|
operator: '>=',
|
|
),
|
|
points: 300,
|
|
rarity: 'legendary',
|
|
isActive: true,
|
|
createdAt: DateTime.now(),
|
|
),
|
|
];
|
|
}
|