101 lines
4.3 KiB
Dart
101 lines
4.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:firebase_auth/firebase_auth.dart';
|
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:onsolgo/core/constants.dart';
|
|
import 'package:onsolgo/core/achievement_manager.dart';
|
|
import 'package:onsolgo/screens/auth/tier_comparison_screen.dart';
|
|
import 'package:cached_network_image/cached_network_image.dart';
|
|
|
|
class LoginScreen extends StatefulWidget {
|
|
const LoginScreen({super.key});
|
|
@override
|
|
State<LoginScreen> createState() => _LoginScreenState();
|
|
}
|
|
|
|
class _LoginScreenState extends State<LoginScreen> {
|
|
final _email = TextEditingController();
|
|
final _pass = TextEditingController();
|
|
final _invite = TextEditingController();
|
|
final _user = TextEditingController();
|
|
bool _isSigningUp = false;
|
|
bool _loading = false;
|
|
|
|
void _handleAuth() async {
|
|
setState(() => _loading = true);
|
|
final messenger = ScaffoldMessenger.of(context);
|
|
try {
|
|
if (_isSigningUp) {
|
|
var codeDoc = await FirebaseFirestore.instance.collection('invite_codes').doc(_invite.text.trim()).get();
|
|
if (!codeDoc.exists || codeDoc['isUsed'] == true) throw "Invalid or Used Invite Code";
|
|
|
|
UserCredential cred = await FirebaseAuth.instance.createUserWithEmailAndPassword(
|
|
email: _email.text.trim(), password: _pass.text.trim());
|
|
|
|
await FirebaseFirestore.instance.collection('users').doc(cred.user!.uid).set({
|
|
'username': _user.text.trim(),
|
|
'role': 'reader',
|
|
'tier': 'free', // DEFAULT TIER
|
|
'rankLevel': 1,
|
|
'uid': cred.user!.uid,
|
|
'streak': 1,
|
|
'lastVisit': FieldValue.serverTimestamp(),
|
|
'pagesRead': 0,
|
|
'chaptersRead': 0,
|
|
'energy': 2,
|
|
'lastEnergyRefill': FieldValue.serverTimestamp(),
|
|
});
|
|
|
|
await codeDoc.reference.update({'isUsed': true});
|
|
AchievementManager.unlock(cred.user!.uid, "initiate");
|
|
} else {
|
|
await FirebaseAuth.instance.signInWithEmailAndPassword(email: _email.text.trim(), password: _pass.text.trim());
|
|
}
|
|
} catch (e) {
|
|
messenger.showSnackBar(SnackBar(content: Text(e.toString())));
|
|
} finally {
|
|
if (mounted) setState(() => _loading = false);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
backgroundColor: Colors.black,
|
|
body: SafeArea(
|
|
child: Center(
|
|
child: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(32),
|
|
child: Column(
|
|
children: [
|
|
CachedNetworkImage(imageUrl: kOnsolBanner, height: 80),
|
|
const SizedBox(height: 40),
|
|
if (_isSigningUp) TextField(controller: _invite, decoration: const InputDecoration(labelText: "INVITE CODE", labelStyle: TextStyle(color: kOnsolGold))),
|
|
if (_isSigningUp) TextField(controller: _user, decoration: const InputDecoration(labelText: "CHOOSE USERNAME")),
|
|
TextField(controller: _email, decoration: const InputDecoration(labelText: "EMAIL")),
|
|
TextField(controller: _pass, decoration: const InputDecoration(labelText: "PASSWORD"), obscureText: true),
|
|
const SizedBox(height: 30),
|
|
_loading ? const CircularProgressIndicator(color: kOnsolGold) : ElevatedButton(
|
|
style: ElevatedButton.styleFrom(minimumSize: const Size(double.infinity, 50), backgroundColor: kOnsolGold, foregroundColor: Colors.black),
|
|
onPressed: _handleAuth,
|
|
child: Text(_isSigningUp ? "JOIN THE ORDER" : "ENTER THE ORDER")
|
|
),
|
|
const SizedBox(height: 15),
|
|
|
|
// NEW TIER COMPARISON LINK
|
|
TextButton(
|
|
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (c) => const TierComparisonScreen())),
|
|
child: const Text("View Tier Benefits & Features", style: TextStyle(color: kOnsolGold, fontSize: 12, decoration: TextDecoration.underline))
|
|
),
|
|
|
|
TextButton(
|
|
onPressed: () => setState(() => _isSigningUp = !_isSigningUp),
|
|
child: Text(_isSigningUp ? "Already a Citizen? Login" : "Redeem Invite", style: const TextStyle(color: Colors.white70))
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |