summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRishi-k-s <rishikrishna.sr@gmail.com>2024-11-15 17:28:20 +0530
committerRishi-k-s <rishikrishna.sr@gmail.com>2024-11-15 17:28:20 +0530
commit136758f36719e43e14d6f5234562c58b332b57e1 (patch)
tree50280d4985313a54665fb43a87d6e8215530fec0
parenta6c0e7d7e2fb8badc4b4ade48438b2d025025366 (diff)
doine nedobrulaist stuffui-feature-branch
-rw-r--r--lib/userpage/Scoreboardpage.dart170
-rw-r--r--lib/userpage/loginpage.dart221
-rw-r--r--lib/userpage/quizpage.dart193
-rw-r--r--lib/userpage/userverificationpage.dart172
-rw-r--r--test_page.dart240
5 files changed, 813 insertions, 183 deletions
diff --git a/lib/userpage/Scoreboardpage.dart b/lib/userpage/Scoreboardpage.dart
index c72a04f..ee79dc0 100644
--- a/lib/userpage/Scoreboardpage.dart
+++ b/lib/userpage/Scoreboardpage.dart
@@ -10,7 +10,7 @@ class ScoreboardPage extends StatefulWidget {
class _ScoreboardPageState extends State<ScoreboardPage> {
final DatabaseReference database = FirebaseDatabase.instance.ref();
- List<Map<String, dynamic>> users = []; // To store user data
+ List<Map<String, dynamic>> users = [];
bool isLoading = true;
@override
@@ -19,20 +19,18 @@ class _ScoreboardPageState extends State<ScoreboardPage> {
_loadUsers();
}
- // Load users from Firebase and sort them by score
Future<void> _loadUsers() async {
final snapshot = await database.child("users").get();
if (snapshot.exists) {
final data = snapshot.value as Map;
users = data.entries.map((e) {
return {
- 'name': e.value['fullName'], // Get the name field
- 'semester': e.value['semester'], // Get the semester field
- 'score': e.value['score'], // Get the score field
+ 'name': e.value['fullName'],
+ 'semester': e.value['semester'],
+ 'score': e.value['score'],
};
}).toList();
- // Sort users by score in descending order
users.sort((a, b) => b['score'].compareTo(a['score']));
setState(() {
@@ -41,27 +39,153 @@ class _ScoreboardPageState extends State<ScoreboardPage> {
}
}
+ Color _getMedalColor(int index) {
+ switch (index) {
+ case 0:
+ return const Color(0xFFFFD700); // Gold
+ case 1:
+ return const Color(0xFFC0C0C0); // Silver
+ case 2:
+ return const Color(0xFFCD7F32); // Bronze
+ default:
+ return Colors.transparent;
+ }
+ }
+
+ Widget _buildUserCard(Map<String, dynamic> user, int index) {
+ final bool isTopThree = index < 3;
+ final medalColor = _getMedalColor(index);
+
+ return Container(
+ margin: const EdgeInsets.only(bottom: 16),
+ decoration: BoxDecoration(
+ color: isTopThree ? medalColor.withOpacity(0.1) : Colors.white,
+ border: Border.all(
+ color: isTopThree ? medalColor : const Color(0xFF3A78C2),
+ width: isTopThree ? 3 : 2,
+ ),
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(16),
+ child: Row(
+ children: [
+ Container(
+ width: 40,
+ height: 40,
+ decoration: BoxDecoration(
+ color: isTopThree ? medalColor : const Color(0xFF4D9FFF),
+ shape: BoxShape.circle,
+ border: Border.all(
+ color: isTopThree ? medalColor.withOpacity(0.7) : const Color(0xFF3A78C2),
+ width: 2,
+ ),
+ ),
+ child: Center(
+ child: Text(
+ '${index + 1}',
+ style: TextStyle(
+ color: isTopThree ? Colors.black : Colors.white,
+ fontWeight: FontWeight.bold,
+ fontSize: 18,
+ ),
+ ),
+ ),
+ ),
+ const SizedBox(width: 16),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ user['name'] ?? "Unknown",
+ style: TextStyle(
+ fontSize: isTopThree ? 20 : 18,
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ ),
+ ),
+ const SizedBox(height: 4),
+ Text(
+ "Semester: ${user['semester'] ?? 'N/A'}",
+ style: TextStyle(
+ fontSize: 16,
+ color: Colors.grey[600],
+ ),
+ ),
+ ],
+ ),
+ ),
+ Container(
+ padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
+ decoration: BoxDecoration(
+ color: isTopThree ? medalColor.withOpacity(0.2) : const Color(0xFF4D9FFF).withOpacity(0.1),
+ borderRadius: BorderRadius.circular(16),
+ border: Border.all(
+ color: isTopThree ? medalColor : const Color(0xFF3A78C2),
+ width: 2,
+ ),
+ ),
+ child: Text(
+ "${user['score']}",
+ style: TextStyle(
+ fontSize: isTopThree ? 20 : 18,
+ fontWeight: FontWeight.bold,
+ color: isTopThree ? Colors.black : const Color(0xFF3A78C2),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
@override
Widget build(BuildContext context) {
return Scaffold(
- appBar: AppBar(title: const Text("Scoreboard")),
- body: Padding(
- padding: const EdgeInsets.all(16.0),
- child: isLoading
- ? const Center(child: CircularProgressIndicator())
- : users.isEmpty
- ? const Center(child: Text("No users found"))
- : ListView.builder(
- itemCount: users.length,
- itemBuilder: (context, index) {
- return ListTile(
- title: Text(users[index]['name'] ?? "Unknown"),
- subtitle: Text("Semester: ${users[index]['semester'] ?? "N/A"}"),
- trailing: Text("Score: ${users[index]['score']}"),
- );
- },
+ body: Container(
+ color: const Color(0xFFFDF6E3),
+ child: SafeArea(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const Text(
+ "Scoreboard",
+ style: TextStyle(
+ fontSize: 32,
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
),
+ ),
+ const SizedBox(height: 24),
+ Expanded(
+ child: isLoading
+ ? const Center(child: CircularProgressIndicator())
+ : users.isEmpty
+ ? const Center(
+ child: Text(
+ "No users found",
+ style: TextStyle(
+ fontSize: 18,
+ color: Color(0xFF3A78C2),
+ ),
+ ),
+ )
+ : ListView.builder(
+ itemCount: users.length,
+ itemBuilder: (context, index) {
+ return _buildUserCard(users[index], index);
+ },
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
),
);
}
-}
+} \ No newline at end of file
diff --git a/lib/userpage/loginpage.dart b/lib/userpage/loginpage.dart
index 0fdda98..66298bc 100644
--- a/lib/userpage/loginpage.dart
+++ b/lib/userpage/loginpage.dart
@@ -1,5 +1,6 @@
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
@@ -10,8 +11,6 @@ class LoginPage extends StatefulWidget {
class _LoginPageState extends State<LoginPage> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
-
- // Controllers for each field
final TextEditingController emailController = TextEditingController();
final TextEditingController fullNameController = TextEditingController();
final TextEditingController semesterController = TextEditingController();
@@ -26,7 +25,7 @@ class _LoginPageState extends State<LoginPage> {
bool _isLoading = false;
bool _iswaiting = false;
- Future<void> _submitData() async {
+ Future<void> _submitData() async {
String question;
if (_formKey.currentState!.validate()) {
question =
@@ -92,82 +91,164 @@ class _LoginPageState extends State<LoginPage> {
}
}
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- body: _iswaiting
- ? const Text(
- "Waiting page.....",
- style: TextStyle(color: Colors.red, fontSize: 30),
- )
- : SingleChildScrollView(
- child: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Form(
- key: _formKey,
- child: Column(
- children: [
- CustomTextField(
- labelText: 'Email', controller: emailController),
- CustomTextField(
- labelText: 'Full Name',
- controller: fullNameController),
- CustomTextField(
- labelText: 'Semester',
- controller: semesterController),
- CustomTextField(
- labelText: 'Question',
- controller: questionController),
- CustomTextField(
- labelText: 'Answer', controller: answerController),
- CustomTextField(
- labelText: 'Option 1', controller: option1Controller),
- CustomTextField(
- labelText: 'Option 2', controller: option2Controller),
- CustomTextField(
- labelText: 'Option 3', controller: option3Controller),
- const SizedBox(height: 20),
- _isLoading
- ? const CircularProgressIndicator() // Show loader if loading
- : ElevatedButton(
- onPressed:
- _submitData, // Call _submitData function
- child: const Text('Submit'),
- ),
- ],
- ),
- ),
+ // Previous methods remain the same (_submitData)...
+
+ Widget _buildStyledTextField(String labelText, TextEditingController controller, {bool isNumeric = false}) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(vertical: 8.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ labelText,
+ style: const TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.bold,
+ color: Color(0xFF3A78C2),
+ ),
+ ),
+ const SizedBox(height: 8),
+ TextFormField(
+ controller: controller,
+ keyboardType: isNumeric ? TextInputType.number : TextInputType.text,
+ inputFormatters: isNumeric ? [FilteringTextInputFormatter.digitsOnly] : null,
+ decoration: InputDecoration(
+ filled: true,
+ fillColor: Colors.white,
+ hintText: 'Enter $labelText',
+ hintStyle: TextStyle(color: Colors.grey.shade400),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: const BorderSide(
+ color: Color(0xFF3A78C2),
+ width: 2,
),
),
- );
- }
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: const BorderSide(
+ color: Color(0xFF4D9FFF),
+ width: 2,
+ ),
+ ),
+ errorBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: const BorderSide(
+ color: Colors.red,
+ width: 2,
+ ),
+ ),
+ focusedErrorBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ borderSide: const BorderSide(
+ color: Colors.red,
+ width: 2,
+ ),
+ ),
+ ),
+ validator: (value) {
+ if (value == null || value.isEmpty) {
+ return 'Please enter $labelText';
+ }
+ return null;
+ },
+ ),
+ ],
+ ),
+ );
}
-class CustomTextField extends StatelessWidget {
- final String labelText;
- final TextEditingController controller;
- const CustomTextField({super.key, required this.labelText, required this.controller});
+ Widget _buildSubmitButton() {
+ return Container(
+ width: double.infinity,
+ height: 56,
+ decoration: BoxDecoration(
+ color: const Color(0xFF4D9FFF),
+ borderRadius: BorderRadius.circular(8),
+ border: Border.all(
+ color: const Color(0xFF3A78C2),
+ width: 3,
+ ),
+ ),
+ child: ElevatedButton(
+ onPressed: _isLoading ? null : _submitData,
+ style: ElevatedButton.styleFrom(
+ backgroundColor: Colors.transparent,
+ shadowColor: Colors.transparent,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(8),
+ ),
+ ),
+ child: _isLoading
+ ? const CircularProgressIndicator(color: Colors.white)
+ : const Text(
+ 'Submit',
+ style: TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ ),
+ ),
+ ),
+ );
+ }
@override
Widget build(BuildContext context) {
- return Padding(
- padding: const EdgeInsets.symmetric(vertical: 8.0),
- child: TextFormField(
- controller: controller,
- decoration: InputDecoration(
- labelText: labelText,
- border: OutlineInputBorder(
- borderRadius: BorderRadius.circular(8.0),
- ),
+ return Scaffold(
+ body: Container(
+ color: const Color(0xFFFDF6E3),
+ child: SafeArea(
+ child: _iswaiting
+ ? const Center(
+ child: Text(
+ "Waiting page.....",
+ style: TextStyle(
+ color: Color(0xFF3A78C2),
+ fontSize: 30,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ )
+ : SingleChildScrollView(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const Text(
+ "Create Quiz",
+ style: TextStyle(
+ fontSize: 32,
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ ),
+ ),
+ const SizedBox(height: 24),
+ Form(
+ key: _formKey,
+ child: Column(
+ children: [
+ _buildStyledTextField('Email', emailController),
+ _buildStyledTextField('Full Name', fullNameController),
+ _buildStyledTextField('Semester', semesterController, isNumeric: true),
+ _buildStyledTextField('Question', questionController),
+ _buildStyledTextField('Answer', answerController),
+ _buildStyledTextField('Option 1', option1Controller),
+ _buildStyledTextField('Option 2', option2Controller),
+ _buildStyledTextField('Option 3', option3Controller),
+ const SizedBox(height: 24),
+ _buildSubmitButton(),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
),
- validator: (value) {
- if (value == null || value.isEmpty) {
- return 'Please enter $labelText';
- }
- return null;
- },
),
);
}
-}
+} \ No newline at end of file
diff --git a/lib/userpage/quizpage.dart b/lib/userpage/quizpage.dart
index 62ac74d..56094e4 100644
--- a/lib/userpage/quizpage.dart
+++ b/lib/userpage/quizpage.dart
@@ -1,11 +1,10 @@
import 'dart:async';
-
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
class QuizPage extends StatefulWidget {
final String email;
- final String userId; // Pass user ID along with email
+ final String userId;
const QuizPage({super.key, required this.email, required this.userId});
@@ -16,11 +15,11 @@ class QuizPage extends StatefulWidget {
class _QuizPageState extends State<QuizPage> {
final DatabaseReference database = FirebaseDatabase.instance.ref();
late StreamController<Map> _questionController;
- int score = 0; // The initial score will be fetched from Firebase
+ int score = 0;
bool isLoading = true;
List<Map> questions = [];
int currentQuestionIndex = 0;
- Set<String> answeredQuestions = <String>{}; // Track answered questions
+ Set<String> answeredQuestions = <String>{};
@override
void initState() {
@@ -29,7 +28,6 @@ class _QuizPageState extends State<QuizPage> {
_loadData();
}
- // Load both the questions and user's score from the database
Future<void> _loadData() async {
try {
// Fetch the user's data from the database
@@ -108,6 +106,12 @@ class _QuizPageState extends State<QuizPage> {
// Check the answer, update score, and load the next random question
Future<void> _checkAnswer(String selectedAnswer, Map question) async {
+ // Get the current gameState from the database
+ final gameStateSnapshot = await database.child("gameState").get();
+ final gameState = gameStateSnapshot.value;
+
+ // Proceed only if the gameState is "start"
+ if (gameState == "start") {
if (selectedAnswer == question['answer']) {
score += 4;
} else {
@@ -122,7 +126,13 @@ class _QuizPageState extends State<QuizPage> {
// Move to the next question (loop through the shuffled list)
_showNextQuestion();
+ } else {
+ // Notify the user that the game is not in progress
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(content: Text('Game is not active currently')),
+ );
}
+}
// Method to update score in Firebase
Future<void> _updateScoreInDatabase() async {
@@ -136,64 +146,133 @@ class _QuizPageState extends State<QuizPage> {
}
}
- @override
- void dispose() {
- super.dispose();
- _questionController.close(); // Close the StreamController
+ Widget _buildOptionButton(String option, int index, Map question) {
+ final List<Color> buttonColors = [
+ const Color(0xFFFF69B4), // Pink
+ const Color(0xFF90EE90), // Green
+ const Color(0xFFFFD700), // Gold
+ const Color(0xFF4D9FFF), // Blue
+ ];
+
+ final List<Color> borderColors = [
+ const Color(0xFFD4527A), // Darker Pink
+ const Color(0xFF6CB76C), // Darker Green
+ const Color(0xFFD4B400), // Darker Gold
+ const Color(0xFF3A78C2), // Darker Blue
+ ];
+
+ return Padding(
+ padding: const EdgeInsets.only(bottom: 16.0),
+ child: InkWell(
+ onTap: () => _checkAnswer(option, question),
+ child: Container(
+ width: double.infinity,
+ padding: const EdgeInsets.symmetric(
+ vertical: 16,
+ horizontal: 24,
+ ),
+ decoration: BoxDecoration(
+ color: buttonColors[index],
+ borderRadius: BorderRadius.circular(8),
+ border: Border.all(
+ color: borderColors[index],
+ width: 3,
+ ),
+ ),
+ child: Text(
+ "${String.fromCharCode(65 + index)}) $option",
+ style: const TextStyle(
+ fontSize: 18,
+ color: Colors.black,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ ),
+ ),
+ );
}
@override
Widget build(BuildContext context) {
return Scaffold(
- appBar: AppBar(title: const Text("Quiz")),
- body: Padding(
- padding: const EdgeInsets.all(16.0),
- child: StreamBuilder<Map>(
- stream: _questionController.stream,
- builder: (context, snapshot) {
- if (isLoading) {
- return const Center(child: CircularProgressIndicator());
- }
-
- // Handle loading state
- if (snapshot.connectionState == ConnectionState.waiting) {
- return const Center(child: CircularProgressIndicator());
- }
-
- // Handle the case when no more questions are available
- if (snapshot.hasData &&
- snapshot.data!['no_more_questions'] == true) {
- return const Center(child: Text("No more questions available."));
- }
-
- // Handle the state when data is available (quiz ongoing)
- if (snapshot.hasData) {
- final question = snapshot.data!;
-
- return Column(
- children: [
- Text(
- question['question'],
- style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
- ),
- const SizedBox(height: 20),
- ...question['options'].map<Widget>((option) {
- return ListTile(
- title: Text(option),
- onTap: () => _checkAnswer(option, question),
- );
- }).toList(),
- const SizedBox(height: 20),
- Text("Score: $score"),
- ],
- );
- }
-
- // Default case (shouldn't hit unless there's an issue)
- return const Center(child: Text("An error occurred."));
- },
+ body: Container(
+ color: const Color(0xFFFDF6E3), // Cream background color
+ child: SafeArea(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: StreamBuilder<Map>(
+ stream: _questionController.stream,
+ builder: (context, snapshot) {
+ if (isLoading) {
+ return const Center(child: CircularProgressIndicator());
+ }
+
+ if (snapshot.connectionState == ConnectionState.waiting) {
+ return const Center(child: CircularProgressIndicator());
+ }
+
+ if (snapshot.hasData && snapshot.data!['no_more_questions'] == true) {
+ return const Center(child: Text("No more questions available."));
+ }
+
+ if (snapshot.hasData) {
+ final question = snapshot.data!;
+
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const Text(
+ "Quiz",
+ style: TextStyle(
+ fontSize: 32,
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ ),
+ ),
+ const SizedBox(height: 40),
+ Text(
+ question['question'],
+ style: const TextStyle(
+ fontSize: 24,
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ ),
+ ),
+ const SizedBox(height: 40),
+ ...List.generate(
+ question['options'].length,
+ (index) => _buildOptionButton(
+ question['options'][index],
+ index,
+ question,
+ ),
+ ),
+ const SizedBox(height: 20),
+ Center(
+ child: Text(
+ "Score: $score",
+ style: const TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ return const Center(child: Text("An error occurred."));
+ },
+ ),
+ ),
),
),
);
}
-}
+
+ @override
+ void dispose() {
+ _questionController.close();
+ super.dispose();
+ }
+} \ No newline at end of file
diff --git a/lib/userpage/userverificationpage.dart b/lib/userpage/userverificationpage.dart
index 3c163ed..2f1676f 100644
--- a/lib/userpage/userverificationpage.dart
+++ b/lib/userpage/userverificationpage.dart
@@ -12,10 +12,8 @@ class UserVerificationPage extends StatefulWidget {
class _UserVerificationPageState extends State<UserVerificationPage> {
final TextEditingController nameController = TextEditingController();
final TextEditingController emailController = TextEditingController();
-
final DatabaseReference database = FirebaseDatabase.instance.ref();
- // Corrected method to find userId by email
Future<String?> _findUserIdByEmail(String email) async {
try {
final snapshot = await database
@@ -25,15 +23,10 @@ class _UserVerificationPageState extends State<UserVerificationPage> {
.once();
if (snapshot.snapshot.exists) {
- // If user exists, retrieve the userId (which is the key of the user)
final data = snapshot.snapshot.value as Map<dynamic, dynamic>;
-
- // Getting the first key (which is the userId)
final userId = data.keys.first;
-
return userId;
} else {
- // User does not exist
print("User not found");
return null;
}
@@ -43,15 +36,11 @@ class _UserVerificationPageState extends State<UserVerificationPage> {
}
}
- // Handle button press and navigate to the quiz page
void _verifyUser() async {
final email = emailController.text.trim();
-
- // Call _findUserIdByEmail to find the userId
final userId = await _findUserIdByEmail(email);
if (userId != null) {
- // If userId is found, navigate to the QuizPage
Navigator.push(
context,
MaterialPageRoute(
@@ -59,9 +48,15 @@ class _UserVerificationPageState extends State<UserVerificationPage> {
),
);
} else {
- // If userId is not found, show an error
ScaffoldMessenger.of(context).showSnackBar(
- const SnackBar(content: Text("User not found. Please register.")),
+ SnackBar(
+ content: const Text("User not found. Please register."),
+ backgroundColor: const Color(0xFFFF6B6B),
+ behavior: SnackBarBehavior.floating,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(10),
+ ),
+ ),
);
}
}
@@ -69,28 +64,139 @@ class _UserVerificationPageState extends State<UserVerificationPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
- appBar: AppBar(title: const Text("User Verification")),
- backgroundColor: Colors.white,
- body: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Column(
- children: [
- TextField(
- controller: nameController,
- decoration: const InputDecoration(labelText: "Name"),
- ),
- TextField(
- controller: emailController,
- decoration: const InputDecoration(labelText: "Email"),
+ backgroundColor: const Color(0xFFFFF3E0), // Warm background color
+ // appBar: AppBar(
+ // title: const Text(
+ // "LOGIN",
+ // style: TextStyle(
+ // fontWeight: FontWeight.bold,
+ // letterSpacing: 2,
+ // ),
+ // ),
+ // backgroundColor: const Color(0xFF4ECDC4), // Bright teal
+ // elevation: 8,
+ // shadowColor: Colors.black,
+ // ),
+ body: Center(
+ child: SingleChildScrollView(
+ child: Padding(
+ padding: const EdgeInsets.all(24.0),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ // Logo or Image placeholder
+ Container(
+ width: 120,
+ height: 120,
+ decoration: BoxDecoration(
+ color: const Color(0xFFFF6B6B), // Coral
+ borderRadius: BorderRadius.circular(20),
+ boxShadow: const [
+ BoxShadow(
+ color: Colors.black,
+ offset: Offset(4, 4),
+ blurRadius: 0,
+ ),
+ ],
+ ),
+ child: const Icon(
+ Icons.person,
+ size: 60,
+ color: Colors.white,
+ ),
+ ),
+ const SizedBox(height: 40),
+ // Name TextField
+ Container(
+ decoration: BoxDecoration(
+ color: Colors.white,
+ border: Border.all(color: Colors.black, width: 3),
+ borderRadius: BorderRadius.circular(15),
+ boxShadow: const [
+ BoxShadow(
+ color: Colors.black,
+ offset: Offset(4, 4),
+ blurRadius: 0,
+ ),
+ ],
+ ),
+ child: TextField(
+ controller: nameController,
+ decoration: const InputDecoration(
+ labelText: "NAME",
+ labelStyle: TextStyle(
+ color: Color(0xFF2C3E50),
+ fontWeight: FontWeight.bold,
+ ),
+ border: InputBorder.none,
+ contentPadding: EdgeInsets.all(16),
+ ),
+ ),
+ ),
+ const SizedBox(height: 20),
+ // Email TextField
+ Container(
+ decoration: BoxDecoration(
+ color: Colors.white,
+ border: Border.all(color: Colors.black, width: 3),
+ borderRadius: BorderRadius.circular(15),
+ boxShadow: const [
+ BoxShadow(
+ color: Colors.black,
+ offset: Offset(4, 4),
+ blurRadius: 0,
+ ),
+ ],
+ ),
+ child: TextField(
+ controller: emailController,
+ decoration: const InputDecoration(
+ labelText: "EMAIL",
+ labelStyle: TextStyle(
+ color: Color(0xFF2C3E50),
+ fontWeight: FontWeight.bold,
+ ),
+ border: InputBorder.none,
+ contentPadding: EdgeInsets.all(16),
+ ),
+ ),
+ ),
+ const SizedBox(height: 40),
+ // Login Button
+ GestureDetector(
+ onTap: _verifyUser,
+ child: Container(
+ width: double.infinity,
+ padding: const EdgeInsets.symmetric(vertical: 16),
+ decoration: BoxDecoration(
+ color: const Color(0xFFFFBE0B), // Bright yellow
+ border: Border.all(color: Colors.black, width: 3),
+ borderRadius: BorderRadius.circular(15),
+ boxShadow: const [
+ BoxShadow(
+ color: Colors.black,
+ offset: Offset(4, 4),
+ blurRadius: 0,
+ ),
+ ],
+ ),
+ child: const Text(
+ "CONTINUE →",
+ textAlign: TextAlign.center,
+ style: TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.bold,
+ color: Colors.black,
+ letterSpacing: 1,
+ ),
+ ),
+ ),
+ ),
+ ],
),
- const SizedBox(height: 20),
- ElevatedButton(
- onPressed: _verifyUser, // Call _verifyUser on button press
- child: const Text("Continue..."),
- ),
- ],
+ ),
),
),
);
}
-}
+} \ No newline at end of file
diff --git a/test_page.dart b/test_page.dart
new file mode 100644
index 0000000..d2ea27e
--- /dev/null
+++ b/test_page.dart
@@ -0,0 +1,240 @@
+import 'package:firebase_database/firebase_database.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+
+class RegistrationPage extends StatefulWidget {
+ const RegistrationPage({super.key});
+
+ @override
+ State<RegistrationPage> createState() => _RegistrationPageState();
+}
+
+class _RegistrationPageState extends State<RegistrationPage> {
+ final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
+ final TextEditingController emailController = TextEditingController();
+ final TextEditingController passwordController = TextEditingController();
+ final TextEditingController confirmPasswordController = TextEditingController();
+ final TextEditingController usernameController = TextEditingController();
+
+ final DatabaseReference database = FirebaseDatabase.instance.ref();
+ bool _isLoading = false;
+
+ // Neo-brutalist colors
+ static const Color primaryColor = Color(0xFFFF6B6B);
+ static const Color secondaryColor = Color(0xFF4ECDC4);
+ static const Color backgroundColor = Color(0xFFFFF9DB);
+ static const Color textColor = Color(0xFF2C3E50);
+
+ Future<void> _register() async {
+ if (_formKey.currentState!.validate()) {
+ if (passwordController.text != confirmPasswordController.text) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(content: Text('Passwords do not match!')),
+ );
+ return;
+ }
+
+ setState(() {
+ _isLoading = true;
+ });
+
+ try {
+ // Create User data
+ final userData = {
+ "email": emailController.text,
+ "username": usernameController.text,
+ // Note: In a real app, you should hash the password
+ "password": passwordController.text,
+ };
+
+ // Save data to Firebase
+ await database.child("users").push().set(userData);
+
+ // Clear form fields
+ emailController.clear();
+ passwordController.clear();
+ confirmPasswordController.clear();
+ usernameController.clear();
+
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(
+ content: Text('Registration successful!'),
+ backgroundColor: primaryColor,
+ ),
+ );
+ } catch (e) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text('Registration failed: $e')),
+ );
+ } finally {
+ setState(() {
+ _isLoading = false;
+ });
+ }
+ }
+ }
+
+ Widget _buildNeoBrutalistTextField(
+ String labelText, TextEditingController controller,
+ {bool isPassword = false}) {
+ return Container(
+ margin: const EdgeInsets.symmetric(vertical: 12),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ labelText.toUpperCase(),
+ style: const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.bold,
+ color: textColor,
+ letterSpacing: 1.5,
+ ),
+ ),
+ const SizedBox(height: 8),
+ Container(
+ decoration: BoxDecoration(
+ color: Colors.white,
+ border: Border.all(color: textColor, width: 3),
+ borderRadius: BorderRadius.circular(8),
+ boxShadow: const [
+ BoxShadow(
+ color: Colors.black,
+ offset: Offset(4, 4),
+ blurRadius: 0,
+ ),
+ ],
+ ),
+ child: TextFormField(
+ controller: controller,
+ obscureText: isPassword,
+ decoration: InputDecoration(
+ hintText: 'Enter $labelText',
+ hintStyle: TextStyle(color: Colors.grey.shade400),
+ contentPadding: const EdgeInsets.symmetric(
+ horizontal: 20,
+ vertical: 16,
+ ),
+ border: InputBorder.none,
+ ),
+ validator: (value) {
+ if (value == null || value.isEmpty) {
+ return 'Please enter $labelText';
+ }
+ if (labelText.contains('Email') &&
+ !value.contains('@')) {
+ return 'Please enter a valid email';
+ }
+ if (labelText.contains('Password') && value.length < 6) {
+ return 'Password must be at least 6 characters';
+ }
+ return null;
+ },
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Widget _buildNeoBrutalistButton() {
+ return Container(
+ width: double.infinity,
+ height: 60,
+ margin: const EdgeInsets.symmetric(vertical: 20),
+ decoration: BoxDecoration(
+ color: primaryColor,
+ border: Border.all(color: Colors.black, width: 3),
+ borderRadius: BorderRadius.circular(8),
+ boxShadow: const [
+ BoxShadow(
+ color: Colors.black,
+ offset: Offset(4, 4),
+ blurRadius: 0,
+ ),
+ ],
+ ),
+ child: Material(
+ color: Colors.transparent,
+ child: InkWell(
+ onTap: _isLoading ? null : _register,
+ child: Center(
+ child: _isLoading
+ ? const CircularProgressIndicator(color: Colors.white)
+ : const Text(
+ 'REGISTER',
+ style: TextStyle(
+ fontSize: 20,
+ fontWeight: FontWeight.bold,
+ color: Colors.white,
+ letterSpacing: 2,
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: backgroundColor,
+ body: SafeArea(
+ child: SingleChildScrollView(
+ padding: const EdgeInsets.all(24.0),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Container(
+ margin: const EdgeInsets.only(bottom: 40),
+ child: const Text(
+ "REGISTER",
+ style: TextStyle(
+ fontSize: 48,
+ fontWeight: FontWeight.bold,
+ color: textColor,
+ letterSpacing: 2,
+ ),
+ ),
+ ),
+ Form(
+ key: _formKey,
+ child: Column(
+ children: [
+ _buildNeoBrutalistTextField('Username', usernameController),
+ _buildNeoBrutalistTextField('Email', emailController),
+ _buildNeoBrutalistTextField(
+ 'Password',
+ passwordController,
+ isPassword: true,
+ ),
+ _buildNeoBrutalistTextField(
+ 'Confirm Password',
+ confirmPasswordController,
+ isPassword: true,
+ ),
+ _buildNeoBrutalistButton(),
+ TextButton(
+ onPressed: () {
+ // Add navigation to login page
+ },
+ child: const Text(
+ 'Already have an account? Login',
+ style: TextStyle(
+ color: secondaryColor,
+ fontSize: 16,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+} \ No newline at end of file