Skip to content
Open
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
192 changes: 192 additions & 0 deletions free income
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(VideoIncomeApp());
}

class VideoIncomeApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Income',
theme: ThemeData(primarySwatch: Colors.green),
home: AuthWrapper(),
);
}
}

class AuthWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.hasData) return HomePage();
return LoginPage();
},
);
}
}

class LoginPage extends StatefulWidget {
@override
State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
final phoneController = TextEditingController();
String verificationId = '';
bool codeSent = false;
final otpController = TextEditingController();

void sendOtp() async {
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: '+88${phoneController.text}',
verificationCompleted: (cred) async {
await FirebaseAuth.instance.signInWithCredential(cred);
},
verificationFailed: (e) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Failed: ${e.message}')));
},
codeSent: (id, resendToken) {
setState(() {
verificationId = id;
codeSent = true;
});
},
codeAutoRetrievalTimeout: (id) {},
);
}

void verifyOtp() async {
final credential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: otpController.text,
);
try {
await FirebaseAuth.instance.signInWithCredential(credential);
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Invalid OTP')));
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Login')),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
if (!codeSent)
TextField(
controller: phoneController,
keyboardType: TextInputType.phone,
decoration: InputDecoration(labelText: 'Phone Number (without +88)'),
),
if (codeSent)
TextField(
controller: otpController,
keyboardType: TextInputType.number,
decoration: InputDecoration(labelText: 'OTP'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: codeSent ? verifyOtp : sendOtp,
child: Text(codeSent ? 'Verify OTP' : 'Send OTP'),
)
],
),
),
);
}
}

class HomePage extends StatefulWidget {
@override
State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
int points = 0;
String userId = FirebaseAuth.instance.currentUser!.uid;

@override
void initState() {
super.initState();
loadPoints();
}

void loadPoints() async {
final doc = await FirebaseFirestore.instance.collection('users').doc(userId).get();
if (doc.exists) {
setState(() {
points = doc.data()?['points'] ?? 0;
});
} else {
await FirebaseFirestore.instance.collection('users').doc(userId).set({'points': 0});
}
}

void watchVideo() async {
setState(() {
points += 2;
});
await FirebaseFirestore.instance.collection('users').doc(userId).update({'points': points});
}

void withdraw() async {
if (points >= 20) {
// Create a withdraw request
await FirebaseFirestore.instance.collection('withdraws').add({
'userId': userId,
'points': 20,
'status': 'pending',
'timestamp': DateTime.now(),
'phone': FirebaseAuth.instance.currentUser!.phoneNumber,
});

setState(() {
points -= 20;
});
await FirebaseFirestore.instance.collection('users').doc(userId).update({'points': points});

ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Withdraw request sent! Admin will process it soon.')),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('You need at least 20 points to withdraw.')),
);
}
}

void logout() async {
await FirebaseAuth.instance.signOut();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Video Income'),
actions: [
IconButton(onPressed: logout, icon: Icon(Icons.logout)),
],
),
body: Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Text('Your points: $points', style: TextStyle(fontSize: 24)),
SizedBox(height: 20),
ElevatedButton(onPressed: watchVideo, child: Text('Watch Video (+2 points)')),
ElevatedButton(onPressed: withdraw, child: Text('Withdraw (20 points = 20 BDT)')),
]),
),
);
}
}