Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions edu_play/lib/MainWrapper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'screens/onboarding_screen.dart';
import 'screens/student_dashboard_screen.dart';
import 'screens/parent_dashboard_screen.dart';
import 'screens/teacher_dashboard_screen.dart';
import 'screens/admin_dashboard_screen.dart';
import 'services/user_provider.dart';

class MainWrapper extends StatelessWidget {
const MainWrapper({super.key});

@override
Widget build(BuildContext context) {
return Consumer<UserProvider>(
builder: (context, userProvider, child) {
final user = userProvider.user;

if (user == null) {
return const OnboardingScreen();
}

switch (user.role) {
case 'Student':
return const StudentDashboardScreen();
case 'Parent':
return const ParentDashboardScreen();
case 'Teacher':
return const TeacherDashboardScreen();
case 'Admin':
return const AdminDashboardScreen();
default:
return const OnboardingScreen();
}
},
);
}
}
12 changes: 12 additions & 0 deletions edu_play/lib/config/app_constants.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:flutter/material.dart';

class AppColors {
static const Color primarySkyBlue = Color(0xFF3B82F6);
static const Color accentWarmYellow = Color(0xFFFACC15);
static const Color secondaryCoralRed = Color(0xFFF87171);
static const Color secondaryGreen = Color(0xFF34D399);
}

class AppConstants {
static const String appName = 'EduPlay';
}
32 changes: 21 additions & 11 deletions edu_play/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,38 +1,48 @@
import 'package:edu_play/screens/onboarding_screen.dart';
import 'package:edu_play/MainWrapper.dart';
import 'package:edu_play/services/user_provider.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'services/notification_service.dart';

void main() {
runApp(const MyApp());
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await NotificationService.initialize();
await Hive.initFlutter();
await Hive.openBox('settings');
await Hive.openBox('lessons');

runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => UserProvider()),
],
child: const MyApp(),
),
);
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'EduPlay',
theme: ThemeData(
// Define the default brightness and colors.
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF3B82F6), // Primary: Sky Blue
primary: const Color(0xFF3B82F6),
secondary: const Color(0xFFFACC15), // Accent: Warm Yellow
error: const Color(0xFFF87171), // Secondary: Coral Red
// Other colors can be defined here as needed
),

// Define the default font family.
textTheme: GoogleFonts.nunitoTextTheme(
Theme.of(context).textTheme,
),

// Use Material 3 design.
useMaterial3: true,
),
home: const OnboardingScreen(),
home: const MainWrapper(),
debugShowCheckedModeBanner: false,
);
}
Expand Down
6 changes: 6 additions & 0 deletions edu_play/lib/models/grade_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Grade {
final String id;
final String name; // e.g., Primary 1, JSS 2

Grade({required this.id, required this.name});
}
4 changes: 4 additions & 0 deletions edu_play/lib/models/lesson_model.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
// Represents a single lesson in a topic.
class Lesson {
final String id;
final String topicId;
final String title;
final String content;
final List<String> mediaUrls;

Lesson({
required this.id,
required this.topicId,
required this.title,
required this.content,
this.mediaUrls = const [],
});
}
4 changes: 4 additions & 0 deletions edu_play/lib/models/quiz_model.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
// Represents a single quiz question.
class QuizItem {
final String id;
final String topicId;
final String question;
final List<String> options;
final String correctAnswer;
final String explanation;

QuizItem({
required this.id,
required this.topicId,
required this.question,
required this.options,
required this.correctAnswer,
required this.explanation,
});
}
7 changes: 7 additions & 0 deletions edu_play/lib/models/subject_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Subject {
final String id;
final String name; // e.g., Mathematics, English
final String gradeId;

Subject({required this.id, required this.name, required this.gradeId});
}
7 changes: 7 additions & 0 deletions edu_play/lib/models/topic_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Topic {
final String id;
final String name; // e.g., Addition, Nouns
final String subjectId;

Topic({required this.id, required this.name, required this.subjectId});
}
80 changes: 76 additions & 4 deletions edu_play/lib/screens/admin_dashboard_screen.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,86 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../services/user_provider.dart';
import '../config/app_constants.dart';

class AdminDashboardScreen extends StatelessWidget {
const AdminDashboardScreen({super.key});

@override
Widget build(BuildContext context) {
return const Scaffold(
appBar: AppBar(title: Text('Admin Dashboard')),
body: Center(
child: Text('Admin Dashboard'),
return Scaffold(
appBar: AppBar(
title: const Text('Admin Dashboard'),
backgroundColor: AppColors.secondaryCoralRed,
foregroundColor: Colors.white,
actions: [
IconButton(
icon: const Icon(Icons.logout),
onPressed: () => Provider.of<UserProvider>(context, listen: false).logout(),
),
],
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"System Overview",
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Row(
children: [
_buildStatCard('Total Schools', '12', Colors.blue),
const SizedBox(width: 16),
_buildStatCard('Total Users', '1,240', Colors.green),
],
),
const SizedBox(height: 24),
const Text(
"Management Tools",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
_buildManagementTile('School Management', Icons.business, () {}),
_buildManagementTile('User Oversight', Icons.people, () {}),
_buildManagementTile('Platform Configuration', Icons.settings, () {}),
_buildManagementTile('Subscription Plans', Icons.card_membership, () {}),
],
),
),
);
}

Widget _buildStatCard(String label, String value, Color color) {
return Expanded(
child: Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(15),
border: Border.all(color: color),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(label, style: TextStyle(color: color, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Text(value, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: color)),
],
),
),
);
}

Widget _buildManagementTile(String title, IconData icon, VoidCallback onTap) {
return Card(
child: ListTile(
leading: Icon(icon, color: AppColors.secondaryCoralRed),
title: Text(title),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: onTap,
),
);
}
Expand Down
58 changes: 58 additions & 0 deletions edu_play/lib/screens/lesson_detail_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:flutter/material.dart';
import '../models/lesson_model.dart';
import '../config/app_constants.dart';

class LessonDetailScreen extends StatelessWidget {
final Lesson lesson;

const LessonDetailScreen({super.key, required this.lesson});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(lesson.title),
backgroundColor: AppColors.primarySkyBlue,
foregroundColor: Colors.white,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (lesson.mediaUrls.isNotEmpty)
Container(
height: 200,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(12),
),
child: const Icon(Icons.image, size: 100, color: Colors.grey),
),
const SizedBox(height: 24),
Text(
lesson.title,
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Text(
lesson.content,
style: const TextStyle(fontSize: 18, height: 1.5),
),
const SizedBox(height: 40),
ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(
minimumSize: const Size(double.infinity, 50),
backgroundColor: AppColors.primarySkyBlue,
foregroundColor: Colors.white,
),
child: const Text('Mark as Completed'),
),
],
),
),
);
}
}
Loading