diff --git a/android/app/build.gradle b/android/app/build.gradle index c73a60d..f9b6da8 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -47,7 +47,7 @@ android { applicationId "com.example.crudapp" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion flutter.minSdkVersion + minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index fbdf1d1..91d51f8 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ { + r.code = 200, + r.msg = "Record Stored successfully !!", + }) + .catchError((e) { + r.code = 500; + r.msg = e.message; + log("${r.msg}"); + }); + return r; + } + + static Future fetchUser(String uid) async { + try { + DocumentSnapshot value = await reference.doc(uid).get(); + return UserModel.fromMap(value.data() as Map); + } catch (e) { + log(e.toString()); + return null; + } + } +} diff --git a/lib/BackEnd/models.dart b/lib/BackEnd/models.dart new file mode 100644 index 0000000..9510f3d --- /dev/null +++ b/lib/BackEnd/models.dart @@ -0,0 +1,99 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'dart:convert'; +import 'package:flutter/foundation.dart'; + +class UserModel { + final String uid; + String? name; + String? mail; + String? number; + String? dob; + List>? notes; + + UserModel({ + required this.uid, + this.name, + this.mail, + this.number, + this.dob, + this.notes, + }); + + UserModel copyWith({ + String? uid, + String? name, + String? mail, + String? number, + String? dob, + List>? notes, + }) { + return UserModel( + uid: uid ?? this.uid, + name: name ?? this.name, + mail: mail ?? this.mail, + number: number ?? this.number, + dob: dob ?? this.dob, + notes: notes ?? this.notes, + ); + } + + Map toMap() { + return { + 'uid': uid, + 'name': name, + 'mail': mail, + 'number': number, + 'dob': dob, + 'notes': notes, + }; + } + + factory UserModel.fromMap(Map map) { + return UserModel( + uid: map['uid'] as String, + name: map['name'] != null ? map['name'] as String : null, + mail: map['mail'] != null ? map['mail'] as String : null, + number: map['number'] != null ? map['number'] as String : null, + dob: map['dob'] != null ? map['dob'] as String : null, + notes: map['notes'] != null + ? List>.from( + (map['notes'] as List).map?>( + (x) => x, + ), + ) + : null, + ); + } + + String toJson() => json.encode(toMap()); + + factory UserModel.fromJson(String source) => + UserModel.fromMap(json.decode(source) as Map); + + @override + String toString() { + return 'UserModel(uid: $uid, name: $name, mail: $mail, number: $number, dob: $dob, notes: $notes)'; + } + + @override + bool operator ==(covariant UserModel other) { + if (identical(this, other)) return true; + + return other.uid == uid && + other.name == name && + other.mail == mail && + other.number == number && + other.dob == dob && + listEquals(other.notes, notes); + } + + @override + int get hashCode { + return uid.hashCode ^ + name.hashCode ^ + mail.hashCode ^ + number.hashCode ^ + dob.hashCode ^ + notes.hashCode; + } +} diff --git a/lib/Drawer/Drawer.dart b/lib/Drawer/Drawer.dart new file mode 100644 index 0000000..2598ff5 --- /dev/null +++ b/lib/Drawer/Drawer.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +class Drawer extends StatelessWidget { + const Drawer({super.key}); + + @override + Widget build(BuildContext context) { + return const Placeholder(); + } +} \ No newline at end of file diff --git a/lib/Drawer/DrawerHeader.dart b/lib/Drawer/DrawerHeader.dart new file mode 100644 index 0000000..f1b47e9 --- /dev/null +++ b/lib/Drawer/DrawerHeader.dart @@ -0,0 +1,66 @@ +// ignore: file_names +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import '../BackEnd/UserData.dart'; +import '../BackEnd/models.dart'; + +class Drawerheader extends StatefulWidget { + const Drawerheader({super.key}); + + @override + State createState() => _DrawerHeaderState(); +} + +class _DrawerHeaderState extends State { + TextEditingController name = TextEditingController(); + TextEditingController email = TextEditingController(); + @override + void initState() { + // dob.text = " "; + super.initState(); + fetchData(); + } + + fetchData() async { + UserModel? d = + await UserData.fetchUser(FirebaseAuth.instance.currentUser!.uid); + // if (d != null) { + setState(() { + name.text = d?.name ?? " "; + // email.text = d.mail ?? ""; + }); + // } else {} + } + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.blue.shade300, + height: 200, + width: double.infinity, + padding: const EdgeInsets.only(top: 20.0), + child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ + Container( + margin: const EdgeInsets.only(bottom: 10), + height: 70, + decoration: const BoxDecoration( + shape: BoxShape.circle, + image: + DecorationImage(image: AssetImage("assets/Images/profile.png")), + ), + ), + Text(name.text.isEmpty ? " " : name.text, + // FirebaseAuth.instance.currentUser!.email.toString(), + style: const TextStyle( + fontSize: 20, + color: Colors.white, + )), + Text( + // email.text.isEmpty ? "Enter Your Email" : email.text, + FirebaseAuth.instance.currentUser!.email.toString(), + style: TextStyle(color: Colors.grey.shade300, fontSize: 10), + ) + ]), + ); + } +} diff --git a/lib/Drawer/Itemheader.dart b/lib/Drawer/Itemheader.dart new file mode 100644 index 0000000..de1eeae --- /dev/null +++ b/lib/Drawer/Itemheader.dart @@ -0,0 +1,75 @@ +import 'package:crudapp/Pages/ChatScreen.dart'; +import 'package:crudapp/Pages/Profile.dart'; +import 'package:crudapp/main.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; + +class Itemheader extends StatefulWidget { + const Itemheader({super.key}); + + @override + State createState() => _ItemheaderState(); +} + +class _ItemheaderState extends State { + @override + Widget build(BuildContext context) { + return Material( + child: Padding( + padding: const EdgeInsets.only(top: 25), + child: Column( + children: [ + ListTile( + leading: const Icon( + Icons.dashboard_outlined, + size: 25, + color: Colors.black, + ), + title: Text( + "Profile", + style: TextStyle(fontSize: 20, color: Colors.grey.shade500), + ), + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const Profile(), + )); + }, + ), + ListTile( + leading: const Icon( + Icons.search_outlined, + size: 25, + color: Colors.black, + ), + title:const Text( + "Search", + style: TextStyle(fontSize: 20, color: Colors.grey), + ), + onTap: () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => const ChatScreen())); + }), + ListTile( + leading: const Icon( + Icons.logout_rounded, + size: 25, + color: Colors.black, + ), + title: Text( + "Log Out", + style: TextStyle(fontSize: 20, color: Colors.grey.shade500), + ), + onTap: () { + FirebaseAuth.instance.signOut().then((value) => Navigator.push( + context, + MaterialPageRoute(builder: (context) => const MainPage()))); + }, + ), + ], + ), + ), + ); + } +} diff --git a/lib/Modal/Notes.dart b/lib/Modal/Notes.dart index 715d5fd..fca73ad 100644 --- a/lib/Modal/Notes.dart +++ b/lib/Modal/Notes.dart @@ -1,6 +1,192 @@ -class Notes { +import 'dart:convert'; +import 'package:flutter/foundation.dart'; + +class Option { String? title; String? body; - Notes({this.title, this.body}); + Option({ + this.title, + this.body, + }); + + Option copyWith({ + String? title, + String? body, + }) { + return Option( + title: title ?? this.title, + body: body ?? this.body, + ); + } + + Map toMap() { + return { + 'title': title, + 'body': body, + }; + } + + factory Option.fromMap(Map map) { + return Option( + title: map['title'] != null ? map['title'] as String : null, + body: map['body'] != null ? map['body'] as String : null, + ); + } + + String toJson() => json.encode(toMap()); + + factory Option.fromJson(String source) => + Option.fromMap(json.decode(source) as Map); + + @override + String toString() => 'Option(title: $title, body: $body)'; + + @override + bool operator ==(covariant Option other) { + if (identical(this, other)) return true; + + return other.title == title && other.body == body; + } + + @override + int get hashCode => title.hashCode ^ body.hashCode; +} + +class Note { + final String title; + final String body; + Note({ + required this.title, + required this.body, + }); + + Note copyWith({ + String? title, + String? body, + }) { + return Note( + title: title ?? this.title, + body: body ?? this.body, + ); + } + + Map toMap() { + return { + 'title': title, + 'body': body, + }; + } + + factory Note.fromMap(Map map) { + return Note( + title: map['title'] as String, + body: map['body'] as String, + ); + } + + String toJson() => json.encode(toMap()); + + factory Note.fromJson(String source) => + Note.fromMap(json.decode(source) as Map); + + @override + String toString() => 'Note(title: $title, body: $body)'; + + @override + bool operator ==(covariant Note other) { + if (identical(this, other)) return true; + + return other.title == title && other.body == body; + } + + @override + int get hashCode => title.hashCode ^ body.hashCode; +} + +class User { + final String name; + final String number; + final String emil; + final String imageurl; + + final List> notes; + + User({ + required this.name, + required this.number, + required this.emil, + required this.imageurl, + required this.notes, + }); + + User copyWith({ + String? name, + String? number, + String? emil, + String? imageurl, + List>? notes, + }) { + return User( + name: name ?? this.name, + number: number ?? this.number, + emil: emil ?? this.emil, + imageurl: imageurl ?? this.imageurl, + notes: notes ?? this.notes, + ); + } + + Map toMap() { + return { + 'name': name, + 'number': number, + 'emil': emil, + 'imageurl': imageurl, + 'Notes': notes, + }; + } + + factory User.fromMap(Map map) { + return User( + name: map['name'] as String, + number: map['number'] as String, + emil: map['emil'] as String, + imageurl: map['imageurl'] as String, + notes: List>.from( + (map['Notes'] as List).map>( + (x) => x, + ), + ), + ); + } + + String toJson() => json.encode(toMap()); + + factory User.fromJson(String source) => + User.fromMap(json.decode(source) as Map); + + @override + String toString() { + return 'User(name: $name, number: $number, emil: $emil, imageurl: $imageurl, Notes: $notes)'; + } + + @override + bool operator ==(covariant User other) { + if (identical(this, other)) return true; + + return other.name == name && + other.number == number && + other.emil == emil && + other.imageurl == imageurl && + listEquals(other.notes, notes); + } + + @override + int get hashCode { + return name.hashCode ^ + number.hashCode ^ + emil.hashCode ^ + imageurl.hashCode ^ + notes.hashCode; + } } diff --git a/lib/Modal/Operation.dart b/lib/Modal/Operation.dart index 9b30f4a..e02ef92 100644 --- a/lib/Modal/Operation.dart +++ b/lib/Modal/Operation.dart @@ -1,5 +1,95 @@ +import 'dart:developer'; + import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:crudapp/BackEnd/UserData.dart'; +import 'package:crudapp/BackEnd/models.dart'; +import 'package:crudapp/Modal/Response.dart'; +import 'package:firebase_auth/firebase_auth.dart'; + +final FirebaseFirestore store = FirebaseFirestore.instance; +// final CollectionReference reference = store.collection("Notes"); +final CollectionReference reference = store.collection("User"); + +class Notes { + static Future addnote(String title, String body) async { + Response r = Response(); + + DocumentReference documentReference = reference.doc(); + + Map data = { + "title": title, + "body": body, + }; + + await documentReference + .set(data) + .whenComplete(() => { + r.code = 200, + r.msg = "Record Stored successfully !!", + }) + .catchError((e) { + r.code = 500; + r.msg = e.message; + log("${r.msg}"); + }); + return r; + } + + static Future setData(Map data) async { + try { + await reference.doc(FirebaseAuth.instance.currentUser!.uid).set(data); + return true; + } catch (e) { + log(e.toString()); + return false; + } + } + + static Future readData() async { + // return reference.snapshots(); + var dd = await reference.doc(FirebaseAuth.instance.currentUser!.uid).get(); + return UserModel.fromMap(dd.data() as Map); + } + static Stream> readData2() { + // return reference.snapshots(); + return reference.doc(FirebaseAuth.instance.currentUser!.uid).snapshots(); + } + // ignore: non_constant_identifier_names + static Future UpdateData( + String title, String body, String docID) async { + Response r = Response(); + DocumentReference docRef = reference.doc(docID); + Map data = { + "title": title, + "body": body, + }; + await docRef + .update(data) + .whenComplete( + () => {r.code = 200, r.msg = "Record Updated Successfully"}) + .catchError((e) { + r.code = 500; + r.msg = e.message; + }); + return r; + } + static Future deletedata({required String docID}) async { + Response r = Response(); + DocumentReference ref = reference.doc(docID); + await ref + .delete() + .whenComplete(() => { + r.code = 200, + r.msg = "Record Deleted Sucessfully", + }) + .catchError((e) { + r.code = 500; + r.msg = e.message; + }); + return r; + } +} diff --git a/lib/Modal/Response.dart b/lib/Modal/Response.dart index 553d19c..408a27e 100644 --- a/lib/Modal/Response.dart +++ b/lib/Modal/Response.dart @@ -6,3 +6,4 @@ class Response { Response({ this.code, this.msg, }); } + diff --git a/lib/Pages/AddNotes.dart b/lib/Pages/AddNotes.dart new file mode 100644 index 0000000..4b95963 --- /dev/null +++ b/lib/Pages/AddNotes.dart @@ -0,0 +1,267 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'package:flutter/material.dart'; +import '../BackEnd/models.dart'; +import '../Modal/Operation.dart'; + +class AddNotes extends StatefulWidget { + const AddNotes({ + Key? key, + required this.sKey, + required this.data, + }) : super(key: key); + + final GlobalKey> sKey; + final UserModel data; + + @override + State createState() => _AddNotesState(); +} + +class _AddNotesState extends State { + TextEditingController title = TextEditingController(); + TextEditingController body = TextEditingController(); + + final formKey = GlobalKey(); + + Future processData() async { + if (formKey.currentState!.validate()) { + Navigator.of(context, rootNavigator: true).pop('dialog'); + + Map d = {'title': title.text, 'body': body.text}; + widget.data.notes ??= []; + setState(() { + widget.data.notes!.add(d); + }); + + bool res = await Notes.setData(widget.data.toMap()); + String msg = ""; + if (res) { + msg = "Note added!!"; + } else { + msg = "Something went wrong!!"; + } + + if (context.mounted) { + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text(msg))); + Navigator.pop(context); + Navigator.of(context, rootNavigator: true).pop(); + } + ScaffoldMessenger.of(widget.sKey.currentState!.context) + .showSnackBar(SnackBar(content: Text(msg))); + // Navigator.pop(context); + + // Response r = await Notes.addnote(title.text, body.text); + // ScaffoldMessenger.of(widget.sKey.currentState!.context) + // .showSnackBar(SnackBar(content: Text("${r.msg}"))); + // log(r); + } + } + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 275, + child: SingleChildScrollView( + child: Form( + key: formKey, + child: Column( + children: [ + TextFormField( + controller: title, + decoration: const InputDecoration( + contentPadding: EdgeInsets.only(left: 20.0), + border: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + label: Text("Title"), + ), + validator: (value) { + if (value == null) { + return "Please enter a title"; + } else if (value.length < 3) { + return "Title should be greater then one word"; + } + return null; + }, + ), + const SizedBox( + height: 20.0, + ), + TextFormField( + controller: body, + keyboardType: TextInputType.multiline, + maxLines: 3, + decoration: InputDecoration( + contentPadding: const EdgeInsets.all(20), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30)), + label: const Text("Body Of The Note"), + ), + validator: (value) { + if (value == null) { + return "Body Can Not Be Empty"; + } + return null; + }, + ), + const SizedBox( + height: 40, + ), + ElevatedButton( + onPressed: () => processData(), + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(Colors.blue), + shape: MaterialStateProperty.all(const StadiumBorder()), + padding: MaterialStateProperty.all(const EdgeInsets.only( + left: 55, right: 55, top: 10, bottom: 10))), + child: const Text( + "Add Note", + style: TextStyle(color: Colors.white, fontSize: 20), + )) + ], + ), + ), + ), + ); + } +} + +class UpdateNotes extends StatefulWidget { + const UpdateNotes({ + super.key, + required this.sKey, + required this.data, + required this.d, + required this.index, + // required this.title, + // required this.body, + // required this.docID, + // required this.sKey, + }); + + final GlobalKey> sKey; + // final String title; + // final String body; + // final String docID; + + final UserModel data; + final Map d; + final int index; + @override + State createState() => _UpdateNotesState(); +} + +class _UpdateNotesState extends State { + final formkey = GlobalKey(); + @override + Widget build(BuildContext context) { + TextEditingController title = + TextEditingController(text: widget.d['title']); + TextEditingController body = TextEditingController(text: widget.d['body']); + Future processData() async { + if (formkey.currentState!.validate()) { + widget.d['title'] = title.text; + widget.d['body'] = body.text; + + widget.data.notes![widget.index] = widget.d; + + String msg = ""; + bool res = await Notes.setData(widget.data.toMap()); + if (res) { + msg = "Updated!!"; + } else { + msg = "Some thing went wrong"; + } + + if (context.mounted) { + ScaffoldMessenger.of(widget.sKey.currentState!.context).showSnackBar( + SnackBar(content: Text(msg)), + ); + Navigator.of(context, rootNavigator: true).pop('dialog'); + } + + // Response r = + // await Notes.UpdateData(title.text, body.text, widget.docID); + // ScaffoldMessenger.of(widget.sKey.currentState!.context).showSnackBar( + // SnackBar(content: Text("${r.msg}")), + // ); + } + } + + return AlertDialog( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + title: const Text( + "Update", + textAlign: TextAlign.center, + ), + content: SizedBox( + height: 275, + child: SingleChildScrollView( + child: Form( + key: formkey, + child: Column( + children: [ + TextFormField( + controller: title, + decoration: const InputDecoration( + contentPadding: EdgeInsets.all(20.0), + border: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + label: Text("Title"), + ), + validator: (value) { + if (value == null) { + return "Title Can Not Be Empty"; + } else if (value.length < 3) { + return "Title Can Not Be Less Then 3 Digits"; + } + return null; + }, + ), + const SizedBox( + height: 20, + ), + TextFormField( + keyboardType: TextInputType.multiline, + maxLines: 3, + controller: body, + decoration: InputDecoration( + contentPadding: const EdgeInsets.all(20), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30)), + label: const Text("Body Of Note"), + ), + validator: (value) { + if (value == null) { + return "Please Enter Content of Body"; + } + return null; + }, + ), + const SizedBox( + height: 20, + ), + ElevatedButton( + onPressed: () { + processData(); + }, + style: ButtonStyle( + shape: MaterialStateProperty.all(const StadiumBorder()), + padding: MaterialStateProperty.all(const EdgeInsets.only( + left: 50, right: 50, top: 10, bottom: 10)), + backgroundColor: MaterialStateProperty.all(Colors.blue), + ), + child: const Text( + "Update", + style: TextStyle(color: Colors.white), + )) + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/Pages/ChatScreen.dart b/lib/Pages/ChatScreen.dart new file mode 100644 index 0000000..0b5cd78 --- /dev/null +++ b/lib/Pages/ChatScreen.dart @@ -0,0 +1,285 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:http/http.dart' as http; +import 'package:selectable/selectable.dart'; +import 'model.dart'; +import 'package:clipboard/clipboard.dart'; + +// const backgroundColor = Color(0xff343541); +// const botBackgroundColor = Color(0xff444654); + +const backgroundColor = Colors.white; +const botBackgroundColor = Colors.white; + +class ChatScreen extends StatefulWidget { + const ChatScreen({super.key}); + + @override + State createState() => _ChatScreenState(); +} + +TextEditingController message = TextEditingController(); + +Future generateResponse(String prompt) async { + const apiKey = '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'; + + var url = Uri.https("api.openai.com", "/v1/completions"); + final response = await http.post( + url, + headers: { + 'Content-Type': 'application/json', + "Authorization": "Bearer $apiKey" + }, + body: json.encode({ + "model": "text-davinci-003", + "prompt": prompt, + 'temperature': 0, + 'max_tokens': 2000, + 'top_p': 1, + 'frequency_penalty': 0.0, + 'presence_penalty': 0.0, + }), + ); + + // Do something with the response + Map newresponse = jsonDecode(response.body); + return newresponse['choices'][0]['text']; +} + +class _ChatScreenState extends State { + final _textController = TextEditingController(); + final _scrollController = ScrollController(); + final List _messages = []; + late bool isLoading; + + @override + void initState() { + super.initState(); + isLoading = false; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + toolbarHeight: 100, + title: const Padding( + padding: EdgeInsets.all(8.0), + child: Text( + "Chat With Chat GPT", + maxLines: 2, + textAlign: TextAlign.center, + style: TextStyle(color: Colors.white), + ), + ), + backgroundColor: Colors.blue, + ), + backgroundColor: backgroundColor, + body: SafeArea( + child: Column( + children: [ + Expanded( + child: _buildList(), + ), + Visibility( + visible: isLoading, + child: const Padding( + padding: EdgeInsets.all(8.0), + child: CircularProgressIndicator( + color: Colors.black, + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + _buildInput(), + _buildSubmit(), + ], + ), + ), + ], + ), + ), + ); + } + + Widget _buildSubmit() { + return Visibility( + visible: !isLoading, + child: Container( + color: botBackgroundColor, + child: IconButton( + icon: const Icon( + Icons.send_rounded, + size: 35, + color: Colors.blue, + ), + onPressed: () async { + setState( + () { + _messages.add( + ChatMessage( + text: _textController.text, + chatMessageType: ChatMessageType.user, + ), + ); + isLoading = true; + }, + ); + var input = _textController.text; + _textController.clear(); + Future.delayed(const Duration(milliseconds: 50)) + .then((_) => _scrollDown()); + generateResponse(input).then((value) { + setState(() { + isLoading = false; + _messages.add( + ChatMessage( + text: value, + chatMessageType: ChatMessageType.bot, + ), + ); + }); + }); + _textController.clear(); + Future.delayed(const Duration(milliseconds: 50)) + .then((_) => _scrollDown()); + }, + ), + ), + ); + } + + Expanded _buildInput() { + return Expanded( + child: TextField( + textCapitalization: TextCapitalization.sentences, + style: const TextStyle(color: Colors.black), + controller: _textController, + decoration: const InputDecoration( + labelText: "Search Something ... ", + hintText: "Write a Email For Leave ...", + fillColor: botBackgroundColor, + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + // focusedBorder: InputBorder.none, + // enabledBorder: InputBorder.none, + // errorBorder: InputBorder.none, + // disabledBorder: InputBorder.none, + ), + ), + ); + } + + ListView _buildList() { + return ListView.builder( + controller: _scrollController, + itemCount: _messages.length, + itemBuilder: (context, index) { + var message = _messages[index]; + return ChatMessageWidget( + text: message.text, + chatMessageType: message.chatMessageType, + ); + }, + ); + } + + void _scrollDown() { + _scrollController.animateTo( + _scrollController.position.maxScrollExtent, + duration: const Duration(milliseconds: 300), + curve: Curves.easeOut, + ); + } +} + +class ChatMessageWidget extends StatelessWidget { + const ChatMessageWidget( + {super.key, required this.text, required this.chatMessageType}); + + final String text; + final ChatMessageType chatMessageType; + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.symmetric(vertical: 10.0), + padding: const EdgeInsets.all(16), + color: chatMessageType == ChatMessageType.bot + ? botBackgroundColor + : backgroundColor, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + chatMessageType == ChatMessageType.bot + ? Container( + margin: const EdgeInsets.only(right: 16.0), + child: CircleAvatar( + backgroundColor: const Color.fromRGBO(16, 163, 127, 1), + child: Image.asset( + 'assets/Images/bot.png', + color: Colors.white, + scale: 1.5, + ), + ), + ) + : Container( + margin: const EdgeInsets.only(right: 16.0), + child: const CircleAvatar( + child: Icon( + Icons.person, + ), + ), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.all(8.0), + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(8.0)), + ), + child: Column( + children: [ + SelectableText( + text.trim(), + style: Theme.of(context) + .textTheme + .bodyLarge + ?.copyWith(color: Colors.black), + onTap: () { + Fluttertoast.showToast( + msg: "Text Copied", + backgroundColor: Colors.grey, + textColor: Colors.white); + FlutterClipboard.copy(text) + .then((value) => print('copied text')); + }, + ), + TextButton( + onPressed: () { + Fluttertoast.showToast( + msg: "Text Copied", + backgroundColor: Colors.grey, + textColor: Colors.white); + FlutterClipboard.copy(text) + .then((value) => print('copied text')); + }, + child: Text("Copy")) + ], + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/Pages/Home.dart b/lib/Pages/Home.dart index 7d8f7de..21fbb53 100644 --- a/lib/Pages/Home.dart +++ b/lib/Pages/Home.dart @@ -1,55 +1,318 @@ -// ignore_for_file: prefer_adjacent_string_concatenation +// ignore_for_file: prefer_adjacent_string_concatenation, prefer_const_constructors +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:crudapp/BackEnd/models.dart'; +import 'package:crudapp/Pages/AddNotes.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; - +import '../Drawer/DrawerHeader.dart'; +import '../Drawer/Itemheader.dart'; +import '../Modal/Operation.dart'; import '../main.dart'; -class HomePage extends StatelessWidget { +class HomePage extends StatefulWidget { const HomePage({super.key}); + @override + State createState() => _HomePageState(); +} + +class _HomePageState extends State { + // final Stream> data = Notes.readData(); + // UserModel? data; + final GlobalKey sKey = GlobalKey(); + + // processData() async { + // UserModel s = await Notes.readData(); + // setState(() { + // data = s; + // }); + // } + + @override + void initState() { + super.initState(); + // processData(); + } + @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.blue, - title: Text( - "Notify", - style: GoogleFonts.lato(fontSize: 25.0, color: Colors.white), - ), - actions: [ - IconButton( - onPressed: () => FirebaseAuth.instance.signOut().then((value) => - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const MainPage()))), - icon: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Icon( - CupertinoIcons.arrow_down_right_circle, - color: Colors.white, - size: 25.0, + return StreamBuilder( + stream: Notes.readData2(), + builder: (context, snapshot) { + UserModel? data; + if (snapshot.hasData) { + var docData = snapshot.data as DocumentSnapshot; + data = UserModel.fromMap(docData.data() as Map); + } + return Scaffold( + key: sKey, + appBar: AppBar( + backgroundColor: Colors.blue, + title: Text( + "Notify", + style: GoogleFonts.lato(fontSize: 25.0, color: Colors.white), + ), + actions: [ + IconButton( + onPressed: () => FirebaseAuth.instance.signOut().then( + (value) => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const MainPage()))), + icon: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: const [ + Icon( + Icons.logout_outlined, + color: Colors.white, + size: 25.0, + ) + ], + )), + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: () => showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text( + "Add Note", + textAlign: TextAlign.center, + ), + content: AddNotes( + data: data!, + sKey: sKey, + ), + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.all(Radius.circular(30))), + ); + }, + ), + child: const Icon( + CupertinoIcons.add, + color: Colors.white, + )), + body: snapshot.hasData + ? Padding( + padding: const EdgeInsets.all(15.0), + child: data!.notes != null + ? ListView( + children: data.notes!.map((e) { + return Card( + elevation: 1, + margin: + EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 16.0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: Padding( + padding: EdgeInsets.only(left: 9, right: 9), + child: ListTile( + title: Text( + e["title"].toUpperCase(), + textAlign: TextAlign.center, + style: GoogleFonts.lato( + letterSpacing: 2, + fontSize: 30, + fontWeight: FontWeight.bold), + ), + subtitle: Padding( + padding: const EdgeInsets.only(top: 20), + child: Text( + "${e["body"]}", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 20, + color: Colors.blueGrey[300]), + ), + ), + trailing: PopupMenuButton( + onSelected: (String result) { + switch (result) { + case 'edit': + break; + case 'delete': + break; + } + }, + itemBuilder: (BuildContext context) => + >[ + PopupMenuItem( + value: 'edit', + child: ListTile( + leading: Icon(Icons.edit), + title: Text('Edit'), + onTap: () { + showDialog( + context: context, + builder: (context) { + return UpdateNotes( + data: data!, + index: + data.notes!.indexOf(e), + d: e, + sKey: sKey, + ); + }, + ); + }, + ), + ), + PopupMenuItem( + value: 'delete', + child: ListTile( + leading: Icon(Icons.delete), + title: Text('Delete'), + onTap: () async { + data!.notes!.remove(e); + bool res = await Notes.setData( + data.toMap()); + String msg = ""; + if (res) { + msg = "Deleted"; + } else { + msg = "Something went wrong"; + } + if (context.mounted) { + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar( + content: Text(msg))); + } + }, + ), + ), + ], + ), + isThreeLine: true, + ), + ), + ); + }).toList(), + ) + : const Center(child: Text("No data!!")), ) - ], - )), - ], - ), - body: SingleChildScrollView( - padding: EdgeInsets.all(10.0), - child: Column( - children: [ - // Text("Hello , " + FirebaseAuth.instance.currentUser.email()), - Text( - "Hello , " + "User", - ) - ], - ), - ), - drawer: Drawer(), - ); + : const Center(child: CircularProgressIndicator()) + // body: StreamBuilder( + // stream: data, + // builder: (BuildContext content, + // AsyncSnapshot> snapshot) { + // if (snapshot.hasData) { + // if (snapshot.data != null) { + // return Padding( + // padding: const EdgeInsets.all(15.0), + // child: ListView( + // children: snapshot.data!['notes'].map((e) { + // return Card( + // elevation: 1, + // margin: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 16.0), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(10), + // ), + // child: Padding( + // padding: EdgeInsets.only(left: 9, right: 9), + // child: ListTile( + // title: Text( + // e["title"].toUpperCase(), + // textAlign: TextAlign.center, + // style: GoogleFonts.lato( + // letterSpacing: 2, + // fontSize: 30, + // fontWeight: FontWeight.bold), + // ), + // subtitle: Padding( + // padding: const EdgeInsets.only(top: 20), + // child: Text( + // "${e["body"]}", + // textAlign: TextAlign.center, + // style: TextStyle( + // fontSize: 20, color: Colors.blueGrey[300]), + // ), + // ), + // trailing: PopupMenuButton( + // onSelected: (String result) { + // switch (result) { + // case 'edit': + // break; + // case 'delete': + // break; + // } + // }, + // itemBuilder: (BuildContext context) => + // >[ + // PopupMenuItem( + // value: 'edit', + // child: ListTile( + // leading: Icon(Icons.edit), + // title: Text('Edit'), + // onTap: () { + // showDialog( + // context: context, + // builder: (context) { + // return UpdateNotes( + // title: e["title"], + // body: e["body"], + // docID: e.id, + // sKey: sKey, + // ); + // }, + // ); + // }, + // ), + // ), + // PopupMenuItem( + // value: 'delete', + // child: ListTile( + // leading: Icon(Icons.delete), + // title: Text('Delete'), + // onTap: () async { + // Response r = + // await Notes.deletedata(docID: e.id); + // if (context.mounted) { + // ScaffoldMessenger.of(context) + // .showSnackBar(SnackBar( + // content: Text("${r.msg}"))); + // } + // }, + // ), + // ), + // ], + // ), + // isThreeLine: true, + // ), + // ), + // ); + // }).toList(), + // ), + // ); + // } else { + // return const Center( + // child: Text("hmm!! No Data"), + // ); + // } + // } else { + // return const Center( + // child: CircularProgressIndicator(), + // ); + // } + // }), + , + drawer: Drawer( + backgroundColor: Colors.white, + child: SingleChildScrollView( + child: Column( + children: const [ + Drawerheader(), + Itemheader(), + ], + ), + ), + ), + ); + }); } } diff --git a/lib/Pages/LogInPage.dart b/lib/Pages/LogInPage.dart index 229b4fc..9b4a31f 100644 --- a/lib/Pages/LogInPage.dart +++ b/lib/Pages/LogInPage.dart @@ -5,24 +5,35 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:google_fonts/google_fonts.dart'; - class LogInPage extends StatelessWidget { const LogInPage({super.key}); @override Widget build(BuildContext context) { - final _formkey = GlobalKey(); + final formkey = GlobalKey(); TextEditingController email = TextEditingController(); TextEditingController password = TextEditingController(); - MoveToHome() async { - if (_formkey.currentState!.validate()) { + moveToHome() async { + if (formkey.currentState!.validate()) { + showDialog(context: context, builder: (context) { + return AlertDialog( + title: Text("Loading ... "), + content: Container(width: 32 , height: 32 , child: CircularProgressIndicator(color: Colors.black,)), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), + ); + },); try { await FirebaseAuth.instance .signInWithEmailAndPassword( email: email.text, password: password.text) .then((value) => Navigator.push(context, - MaterialPageRoute(builder: (context) => HomePage()))); + MaterialPageRoute(builder: (context) => const HomePage()))); + Fluttertoast.showToast( + msg: 'Log In Successfully :) ', + backgroundColor: Colors.grey, + ); } on FirebaseAuthException catch (e) { if (e.code == "invalid-email") { return showDialog( @@ -30,6 +41,18 @@ class LogInPage extends StatelessWidget { builder: (context) { return AlertDialog( content: const Text("Please Enter A Valid Email"), + actions: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("OK")) + ], + ) + ], + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), ); }, ); @@ -39,6 +62,81 @@ class LogInPage extends StatelessWidget { builder: (context) { return AlertDialog( content: const Text("Wrong Password"), + actions: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("OK")) + ], + ) + ], + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + ); + }, + ); + } else if (e.code == "network-request-failed") { + return showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: const Text("No Internet Connection"), + actions: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("OK")) + ], + ) + ], + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + ); + }, + ); + } else if (e.code == "unknown") { + return showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: const Text("Something Went Wrong"), + actions: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("OK")) + ], + ) + ], + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + ); + }, + ); + } else if (e.code == "user-not-found") { + return showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: const Text("Something Went Wrong"), + actions: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("OK")) + ], + ) + ], + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), ); }, ); @@ -46,8 +144,10 @@ class LogInPage extends StatelessWidget { // print(e); log(e.code); } - Navigator.push( - context, MaterialPageRoute(builder: (context) => LogInPage())); + if (context.mounted) { + Navigator.push(context, + MaterialPageRoute(builder: (context) => const LogInPage())); + } } } @@ -55,9 +155,9 @@ class LogInPage extends StatelessWidget { body: SafeArea( child: SingleChildScrollView( child: Form( - key: _formkey, + key: formkey, child: Column(children: [ - SizedBox( + const SizedBox( height: 50.0, ), Padding( @@ -70,20 +170,17 @@ class LogInPage extends StatelessWidget { // fit: BoxFit.cover, ), ), - SizedBox( + const SizedBox( height: 30, ), Padding( - padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0), - child: Container( - // alignment: Alignment.center, - child: Text( - "Log In", - style: GoogleFonts.lato(fontSize: 50.0, color: Colors.blue), - ), + padding: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0), + child: Text( + "Log In", + style: GoogleFonts.lato(fontSize: 50.0, color: Colors.blue), ), ), - SizedBox( + const SizedBox( height: 10, ), Padding( @@ -92,7 +189,7 @@ class LogInPage extends StatelessWidget { child: TextFormField( controller: email, decoration: InputDecoration( - suffixIcon: Icon(CupertinoIcons.mail), + suffixIcon: const Icon(CupertinoIcons.mail), hintText: "username@gmail.com", labelText: "Enter Email", border: OutlineInputBorder( @@ -105,8 +202,8 @@ class LogInPage extends StatelessWidget { }, ), ), - SizedBox( - height: 10, + const SizedBox( + height: 5, ), Padding( padding: @@ -115,7 +212,7 @@ class LogInPage extends StatelessWidget { obscureText: true, controller: password, decoration: InputDecoration( - suffixIcon: Icon(CupertinoIcons.lock), + suffixIcon: const Icon(CupertinoIcons.lock), hintText: "Abcd@54#87", labelText: "Enter Password", border: OutlineInputBorder( @@ -128,22 +225,42 @@ class LogInPage extends StatelessWidget { }, ), ), - SizedBox( + const SizedBox( height: 10.0, ), ElevatedButton( onPressed: () { - MoveToHome(); + moveToHome(); }, - child: Text( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(Colors.blue), + shape: MaterialStateProperty.all( + const RoundedRectangleBorder( + borderRadius: + BorderRadius.all(Radius.circular(10)))), + padding: MaterialStateProperty.all(const EdgeInsets.only( + left: 130, right: 130, top: 10, bottom: 10)), + elevation: MaterialStateProperty.all(1)), + child: const Text( "Log In", style: TextStyle( - color: Colors.white, fontWeight: FontWeight.bold), + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold), )), - TextButton( - onPressed: () => Navigator.push(context, - MaterialPageRoute(builder: (context) => SignUpPage())), - child: Text("Create An Account")), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text("Don't Have an Account ?"), + TextButton( + onPressed: () => Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const SignUpPage())), + child: const Text("Create An Account")), + ], + ), ]), ), ), diff --git a/lib/Pages/Profile.dart b/lib/Pages/Profile.dart new file mode 100644 index 0000000..62022c5 --- /dev/null +++ b/lib/Pages/Profile.dart @@ -0,0 +1,350 @@ +import 'dart:developer'; + +import 'package:crudapp/BackEnd/models.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:intl/intl.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import '../BackEnd/UserData.dart'; + +class Profile extends StatefulWidget { + const Profile({super.key}); + + @override + State createState() => _ProfileState(); +} + +class _ProfileState extends State { + final GlobalKey key1 = GlobalKey(); + bool hasData = false; + + bool emailverify = false; + TextEditingController dob = TextEditingController(); + TextEditingController name = TextEditingController(); + TextEditingController email = TextEditingController(); + TextEditingController number = TextEditingController(); + final formkey1 = GlobalKey(); + @override + void initState() { + // dob.text = " "; + email.text = FirebaseAuth.instance.currentUser!.email.toString(); + super.initState(); + fetchData(); + } + + void sendmail() async { + Fluttertoast.showToast(msg: "Email Has Been Send Sucessfully :) "); + try { + final user = FirebaseAuth.instance.currentUser!; + await user.sendEmailVerification(); + } catch (e) { + // Fluttertoast.showToast(msg: e.toString(), backgroundColor: Colors.grey); + log(e.toString()); + } + } + + fetchData() async { + UserModel? d = + await UserData.fetchUser(FirebaseAuth.instance.currentUser!.uid); + if (d != null) { + setState(() { + dob.text = d.dob ?? ""; + name.text = d.name ?? ""; + // email.text = d.mail ?? ""; + + number.text = d.number ?? ""; + hasData = true; + }); + } else {} + } + + void movetosavedata() async { + if (formkey1.currentState!.validate()) { + try { + Navigator.of(context, rootNavigator: true).pop('dialog'); + UserModel data = UserModel( + uid: FirebaseAuth.instance.currentUser!.uid, + dob: dob.text, + mail: email.text, + name: name.text, + number: number.text); + await UserData.profile(data, FirebaseAuth.instance.currentUser!.uid); + // ScaffoldMessenger.of(widget.skey.currentState!.context).showSnackBar(SnackBar(content: Text("${r.msg}"))); + Fluttertoast.showToast( + msg: "Profile Updated", + backgroundColor: Colors.grey, + fontSize: 20, + ); + } catch (e) { + log(e.toString()); + } + } + } + + uploadImage() async { + await ImagePicker().pickImage( + source: ImageSource.gallery, + maxWidth: 512, + maxHeight: 512, + imageQuality: 75); + // Reference ref = FirebaseFirestore.instance.ref().child("Profile.jpg"); + // await reference.putFile(File(image!.path)); + // ref.get + } + + @override + Widget build(BuildContext context) { + return Container( + decoration: const BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [Colors.purple, Colors.orange, Colors.indigo])), + child: Scaffold( + key: key1, + appBar: AppBar( + backgroundColor: Colors.blue, + ), + body: SingleChildScrollView( + child: Column( + children: [ + GestureDetector( + onTap: () { + uploadImage(); + }, + child: Container( + margin: const EdgeInsets.only(top: 20), + height: 95, + decoration: const BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + image: AssetImage("assets/Images/profile.png")), + ), + ), + ), + Container( + margin: const EdgeInsets.only(top: 10), + height: 70, + width: double.infinity, + child: Column( + children: [ + Text( + name.text.isEmpty ? "Make Your Profile" : name.text, + // data.name, + style: TextStyle( + fontSize: 30, + color: Colors.grey[400], + fontWeight: FontWeight.bold), + ), + Text( + email.text.isEmpty + ? " Enter Detailes Below " + : email.text, + style: TextStyle( + fontSize: 18, + color: Colors.grey[400], + fontWeight: FontWeight.w100), + ), + ], + ), + ), + const SizedBox( + height: 10, + ), + const Divider( + color: Colors.grey, + height: 5, + thickness: 1, + ), + Container( + margin: const EdgeInsets.only(top: 20, left: 10, right: 10), + child: SingleChildScrollView( + child: Form( + key: formkey1, + child: Column( + children: [ + TextFormField( + controller: name, + decoration: InputDecoration( + suffixIcon: Icon( + Icons.near_me, + size: 30, + color: Colors.blue[200], + ), + labelText: "Name", + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30)), + ), + ), + const SizedBox( + height: 15, + ), + Row( + children: [ + SizedBox( + width: MediaQuery.of(context).size.width - 140, + height: 70, + child: TextFormField( + enabled: false, + // controller: email, + initialValue: + FirebaseAuth.instance.currentUser!.email, + decoration: InputDecoration( + suffixIcon: IconButton( + onPressed: () { + emailverify = FirebaseAuth.instance + .currentUser!.emailVerified; + log("$emailverify"); + if (emailverify) { + Fluttertoast.showToast( + msg: "Email Already Verified", + backgroundColor: Colors.grey); + } else { + sendmail(); + } + }, + icon: Icon( + Icons.email_rounded, + size: 30, + color: Colors.blue[500], + )), + // suffixText: TextButton(onPressed: () => , child: Text("Verify"), ), + labelText: " Email", + + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30)), + ), + ), + ), + const SizedBox(width: 5), + SizedBox( + width: 100, + child: Center( + child: !FirebaseAuth + .instance.currentUser!.emailVerified + ? TextButton( + onPressed: () async { + await FirebaseAuth + .instance.currentUser! + .sendEmailVerification(); + // ignore: use_build_context_synchronously + ScaffoldMessenger.of(context) + .showSnackBar( + const SnackBar( + content: Text( + "Verification mail sent to your email, check your inbox."), + ), + ); + }, + child: const Text("Verify Mail")) + : Text("Verified", + style: TextStyle( + color: Colors.green.shade800)), + ), + ) + ], + ), + const SizedBox( + height: 15, + ), + TextFormField( + controller: number, + keyboardType: TextInputType.number, + decoration: InputDecoration( + suffixIcon: Icon( + Icons.numbers_rounded, + size: 30, + color: Colors.blue[200], + ), + labelText: " Number", + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30)), + ), + validator: (value) { + if (value!.length != 10) { + return "Please Enter a Valid Number "; + } + return null; + }, + ), + const SizedBox( + height: 15, + ), + TextFormField( + controller: dob, + decoration: InputDecoration( + suffixIcon: const Icon( + Icons.calendar_today, + color: Colors.blue, + ), + labelText: "DOB", + // label: Padding(padding: EdgeInsets.only(left: 1)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30)), + ), + readOnly: true, + onTap: () async { + DateTime? pickedDate = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: DateTime(1950), + lastDate: DateTime(2100)); + + if (pickedDate != null) { + String formattedDate = + DateFormat('yyyy-MM-dd').format(pickedDate); + setState(() { + dob.text = formattedDate; + }); + } else {} + }, + ), + const SizedBox( + height: 20, + ), + ElevatedButton.icon( + onPressed: () { + movetosavedata(); + }, + icon: const Icon( + Icons.send, + color: Colors.white, + // size: 30, + ), + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(Colors.blue), + shape: MaterialStateProperty.all( + const RoundedRectangleBorder( + borderRadius: + BorderRadius.all(Radius.circular(30)))), + padding: MaterialStateProperty.all( + const EdgeInsets.only( + left: 125, + right: 125, + top: 10, + bottom: 10)), + elevation: MaterialStateProperty.all(1), + ), + label: Text( + hasData ? "Update" : "Submit", + style: const TextStyle( + fontSize: 17, + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/Pages/SignUpPage.dart b/lib/Pages/SignUpPage.dart index b7d74d0..1cc5b9a 100644 --- a/lib/Pages/SignUpPage.dart +++ b/lib/Pages/SignUpPage.dart @@ -1,35 +1,84 @@ -import 'dart:developer'; +// ignore_for_file: prefer_const_constructors, non_constant_identifier_names, no_leading_underscores_for_local_identifiers +import 'dart:developer'; import 'package:crudapp/Pages/LogInPage.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import '../BackEnd/UserData.dart'; class SignUpPage extends StatelessWidget { const SignUpPage({super.key}); @override Widget build(BuildContext context) { + bool circular = false; final _formkey = GlobalKey(); TextEditingController email = TextEditingController(); TextEditingController password = TextEditingController(); MoveToLog() async { if (_formkey.currentState!.validate()) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: SizedBox( + height: 32, + width: 32, + child: CircularProgressIndicator( + color: Colors.black, + ), + ), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + ); + }, + ); try { await FirebaseAuth.instance .createUserWithEmailAndPassword( email: email.text, password: password.text.trim()) - .then((value) => Navigator.push(context, - MaterialPageRoute(builder: (context) => LogInPage()))); + .then( + (value) async { + await UserData.userdata(value.user!.uid); + if (context.mounted) { + Navigator.push(context, + MaterialPageRoute(builder: (context) => const LogInPage())); + } + }, + ); + Fluttertoast.showToast( + msg: 'Account Created Successfully :)', + backgroundColor: Colors.grey, + ); } on FirebaseAuthException catch (e) { if (e.code == "invalid-email") { showDialog( context: context, builder: (context) { return AlertDialog( - content: const Text("Please Enter A Valid Email"), + content: const Text( + "Please Enter A Valid Email", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + actions: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + TextButton( + child: Text("OK"), + onPressed: () { + Navigator.pop(context); + }, + ) + ], + ) + ], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), ); }, ); @@ -39,6 +88,62 @@ class SignUpPage extends StatelessWidget { builder: (context) { return AlertDialog( content: const Text("PLease Enter A Strong Password"), + actions: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text("OK")) + ], + ) + ], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + ); + }, + ); + } else if (e.code == "email-already-in-use") { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: + const Text("This Email is Already Registered With Us"), + actions: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text("OK")) + ], + ) + ], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), + ); + }, + ); + } else if (e.code == "network-request-failed") { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: + const Text("Network Error Please Check Your Internet"), + actions: [ + ButtonBar( + alignment: MainAxisAlignment.center, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text("OK")) + ], + ) + ], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(30))), ); }, ); @@ -56,25 +161,22 @@ class SignUpPage extends StatelessWidget { child: Column(children: [ SvgPicture.asset( "assets/Images/referal.svg", - height: 300.0, - width: 300.0, + height: 280.0, + width: 280.0, fit: BoxFit.cover, ), SizedBox( - height: 30, + height: 20, ), Padding( padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0), - child: Container( - // alignment: Alignment.center, - child: Text( - "Register", - style: GoogleFonts.lato(fontSize: 50.0, color: Colors.blue), - ), + child: Text( + "Register", + style: GoogleFonts.lato(fontSize: 50.0, color: Colors.blue), ), ), SizedBox( - height: 10, + height: 5, ), Padding( padding: @@ -96,7 +198,7 @@ class SignUpPage extends StatelessWidget { ), ), SizedBox( - height: 10, + height: 5, ), Padding( padding: @@ -113,7 +215,7 @@ class SignUpPage extends StatelessWidget { validator: (value) { if (value!.isEmpty) { return "Password Can Not Be Empty"; - } else if (value.length > 6) { + } else if (value.length < 6) { return "Password Should Be Greater Then 6 Digits"; } return null; @@ -121,7 +223,7 @@ class SignUpPage extends StatelessWidget { ), ), SizedBox( - height: 10, + height: 5, ), Padding( padding: @@ -147,17 +249,33 @@ class SignUpPage extends StatelessWidget { ), ElevatedButton( onPressed: () { + // showDialog(context: context, builder: Container(height: 100 , width: 100 , backgroundColor )); MoveToLog(); }, + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(Colors.blue), + shape: MaterialStateProperty.all(RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(10)))), + padding: MaterialStateProperty.all(EdgeInsets.only( + left: 125, right: 125, top: 10, bottom: 10))), child: Text( "Sign Up", style: TextStyle( - color: Colors.white, fontWeight: FontWeight.bold), + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 20), )), - TextButton( - onPressed: () => Navigator.push(context, - MaterialPageRoute(builder: (context) => LogInPage())), - child: Text("Log In")), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text("Already Have an Account ?"), + TextButton( + onPressed: () => Navigator.push(context, + MaterialPageRoute(builder: (context) => LogInPage())), + child: Text("Log In")), + ], + ), SizedBox( height: 10.0, ) diff --git a/lib/Pages/model.dart b/lib/Pages/model.dart new file mode 100644 index 0000000..b55ae9a --- /dev/null +++ b/lib/Pages/model.dart @@ -0,0 +1,11 @@ +enum ChatMessageType { user, bot } + +class ChatMessage { + ChatMessage({ + required this.text, + required this.chatMessageType, + }); + + final String text; + final ChatMessageType chatMessageType; +} \ No newline at end of file diff --git a/lib/Routes/Routes.dart b/lib/Routes/Routes.dart index 80080ee..d65f177 100644 --- a/lib/Routes/Routes.dart +++ b/lib/Routes/Routes.dart @@ -1,7 +1,7 @@ -import 'package:flutter/material.dart'; - class Routes { - static String SignUpPage = "/SignUpPage"; - static String LogInPage = "/LogInPage"; - static String HomePage = "/HomePage"; + static String signUpPage = "/SignUpPage"; + static String logInPage = "/LogInPage"; + static String homePage = "/HomePage"; + static String profile = "/Profile"; + static String chatScreen = "/ChatScreen"; } diff --git a/lib/Theme/Theme.dart b/lib/Theme/Theme.dart index 477e76c..c3f7080 100644 --- a/lib/Theme/Theme.dart +++ b/lib/Theme/Theme.dart @@ -3,29 +3,34 @@ import 'package:google_fonts/google_fonts.dart'; class MyTheme { static ThemeData lightData(BuildContext context) => ThemeData( - // useMaterial3: true, - primarySwatch: Colors.blue, - fontFamily: GoogleFonts.poppins().fontFamily, - appBarTheme: AppBarTheme( - color: Colors.white, - elevation: 0.0, - iconTheme: IconThemeData(color: Colors.white), - toolbarTextStyle: Theme.of(context).textTheme.bodyText2, - titleTextStyle: Theme.of(context).textTheme.headline6, - )); + useMaterial3: true, + primarySwatch: Colors.blue, + fontFamily: GoogleFonts.poppins().fontFamily, + appBarTheme: const AppBarTheme( + color: Colors.white, + elevation: 0.0, + iconTheme: IconThemeData(color: Colors.white), + // backgroundColor: Colors.blue.shade300, + ), + scaffoldBackgroundColor: Colors.white, + colorScheme: ColorScheme.light( + primary: Colors.blue, + secondary: Colors.blue.shade200, + ), + ); static ThemeData darkData(BuildContext context) => ThemeData( - // useMaterial3: true, + useMaterial3: true, primarySwatch: Colors.deepOrange, fontFamily: GoogleFonts.poppins().fontFamily, appBarTheme: AppBarTheme( color: Colors.black, elevation: 0.0, - iconTheme: IconThemeData(color: Colors.black), - toolbarTextStyle: Theme.of(context).textTheme.bodyText2, - titleTextStyle: Theme.of(context).textTheme.headline6, + iconTheme: const IconThemeData(color: Colors.black), + toolbarTextStyle: Theme.of(context).textTheme.bodyMedium, + titleTextStyle: Theme.of(context).textTheme.titleLarge, )); - static Color creamColor = Color(0xfff5f5f5); - static Color darkColor = Color.fromARGB(255, 0, 0, 0); + static Color creamColor = const Color(0xfff5f5f5); + static Color darkColor = const Color.fromARGB(255, 0, 0, 0); } diff --git a/lib/main.dart b/lib/main.dart index 58698b0..62ce158 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,13 @@ -import 'package:crudapp/Pages/LogInPage.dart'; -import 'package:crudapp/Pages/SignUpPage.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; +import 'Pages/ChatScreen.dart'; import 'Pages/Home.dart'; +import 'Pages/LogInPage.dart'; +import 'Pages/Profile.dart'; +import 'Pages/SignUpPage.dart'; import 'Routes/Routes.dart'; import 'Theme/Theme.dart'; -import 'package:firebase_core/firebase_core.dart'; import 'firebase_options.dart'; void main() async { @@ -13,7 +15,7 @@ void main() async { await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); - runApp(MyApp()); + runApp(const MyApp()); } class MyApp extends StatelessWidget { @@ -27,9 +29,11 @@ class MyApp extends StatelessWidget { debugShowCheckedModeBanner: false, home: const MainPage(), routes: { - Routes.SignUpPage: (context) => SignUpPage(), - Routes.LogInPage: (context) => LogInPage(), - Routes.HomePage: (context) => HomePage(), + Routes.signUpPage: (context) => const SignUpPage(), + Routes.logInPage: (context) => const LogInPage(), + Routes.homePage: (context) => const HomePage(), + Routes.profile: (context) => const Profile(), + Routes.chatScreen: (context) => const ChatScreen(), }, ); } @@ -57,3 +61,8 @@ class _MainPageState extends State { ); } } + + +// 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 + +// Trywithadi API KEY :- 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 \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 5eee464..85a1978 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "3ff770dfff04a67b0863dff205a0936784de1b87a5e99b11c693fc10e66a9ce3" + sha256: "6215ac7d00ed98300b72f45ed2b38c2ca841f9f4e6965fab33cbd591e45e4473" url: "https://pub.dev" source: hosted - version: "1.0.12" + version: "1.0.13" async: dependency: transitive description: @@ -41,6 +41,23 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + chat_gpt_sdk: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "7e6565831cd9b8b74a7b376042f952d6c54bea60" + url: "https://github.com/iampawan/Flutter-ChatGPT.git" + source: git + version: "1.0.2+4" + clipboard: + dependency: "direct main" + description: + name: clipboard + sha256: "2ec38f0e59878008ceca0ab122e4bfde98847f88ef0f83331362ba4521f565a9" + url: "https://pub.dev" + source: hosted + version: "0.1.3" clock: dependency: transitive description: @@ -53,26 +70,26 @@ packages: dependency: "direct main" description: name: cloud_firestore - sha256: a851106a2169c15614047b75ea10d0346650352c6669ab482306572aa4ed9a7d + sha256: "9e775f9df26a165444bd5240f70bfee6f11b35c5e913e93ed4b06bf50b231325" url: "https://pub.dev" source: hosted - version: "4.3.1" + version: "4.3.2" cloud_firestore_platform_interface: dependency: transitive description: name: cloud_firestore_platform_interface - sha256: "1fac512fef2bfe84ca7f372defbd9dd8efb108be96854db9023739a5b2aa9977" + sha256: ab35c068896ff769ce7e8de8198228d512e7f056fc8f26b2ff53ea3f97c8545f url: "https://pub.dev" source: hosted - version: "5.10.1" + version: "5.10.2" cloud_firestore_web: dependency: transitive description: name: cloud_firestore_web - sha256: "3fd9581c1447b6e8db6d0f19d0140b196a70ecf582bd1f71e7141fe9abf10ddb" + sha256: b7b52c2ad50d1105f2e0585a34288da415cf9d1037470985c7c57cce7b06d95f url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" collection: dependency: transitive description: @@ -81,6 +98,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" + url: "https://pub.dev" + source: hosted + version: "0.3.3+4" crypto: dependency: transitive description: @@ -97,6 +122,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + dio: + dependency: transitive + description: + name: dio + sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8" + url: "https://pub.dev" + source: hosted + version: "4.0.6" + dob_input_field: + dependency: "direct main" + description: + name: dob_input_field + sha256: "35e75d922d025febc7d272f81a39fcff82f9ab8fde50a44a32c74c5eb237ea3a" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + email_auth: + dependency: "direct main" + description: + name: email_auth + sha256: a382b6d510c2f6a5dad5e424b693168c65681fff29d36d0abec7916472aaba1b + url: "https://pub.dev" + source: hosted + version: "1.0.0" + equatable: + dependency: transitive + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" fake_async: dependency: transitive description: @@ -125,79 +182,95 @@ packages: dependency: "direct main" description: name: firebase_auth - sha256: ac3c7c8022c1032c1dc7d16e62db1d6f1e2fbdc8c1039ee706d8deb45eca3a42 + sha256: "843e307e9b7faa026dd9970e584b5d53265fb5a0c4323883fecdce89ec05d56a" url: "https://pub.dev" source: hosted - version: "4.2.5" + version: "4.2.6" firebase_auth_platform_interface: dependency: transitive description: name: firebase_auth_platform_interface - sha256: "325d934e21826b3e7030f5018ef61927e2083b4c4fb25218ddef6ffc0012b717" + sha256: "8702baa08ad5aa6daa023082d612ca168bf3f7de81e3d56e1df18321f76d675f" url: "https://pub.dev" source: hosted - version: "6.11.7" + version: "6.11.8" firebase_auth_web: dependency: transitive description: name: firebase_auth_web - sha256: "3fb9fafcd3541005a309c1a696f7df6294893a0c44f010f4ed1b0ded4793c858" + sha256: "0c01b9c772ee730df03ac92102e538873558f908d6e42602f6ff9c61dead8d58" url: "https://pub.dev" source: hosted - version: "5.2.4" + version: "5.2.5" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: c129209ba55f3d4272c89fb4a4994c15bea77fb6de63a82d45fb6bc5c94e4355 + sha256: be13e431c0c950f0fc66bdb67b41b8059121d7e7d8bbbc21fb59164892d561f8 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.5.0" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: "5fab93f5b354648efa62e7cc829c90efb68c8796eecf87e0888cae2d5f3accd4" + sha256: "5615b30c36f55b2777d0533771deda7e5730e769e5d3cb7fda79e9bed86cfa55" url: "https://pub.dev" source: hosted - version: "4.5.2" + version: "4.5.3" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: "18b35ce111b0a4266abf723c825bcf9d4e2519d13638cc7f06f2a8dd960c75bc" + sha256: "4b3a41410f3313bb95fd560aa5eb761b6ad65c185de772c72231e8b4aeed6d18" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" firebase_database: dependency: "direct main" description: name: firebase_database - sha256: d2ee0e52955cfd55ab716a48a71b85b727cde8542c4deb3a9013b2812dd1891e + sha256: "5fa2c5128d0057b9af2fdc9124282ce8073f73adb8b0456d78120d1e578f5cda" url: "https://pub.dev" source: hosted - version: "10.0.9" + version: "10.0.10" firebase_database_platform_interface: dependency: transitive description: name: firebase_database_platform_interface - sha256: "1329ade83b77b7b3158f1e9b3d332541ec398481b5d4ad213d94de7a575c07b6" + sha256: d7e03c4422a82b18624f13dc3c022d2dd98f8e28e71dd265d1ac341269d8a92a url: "https://pub.dev" source: hosted - version: "0.2.2+17" + version: "0.2.2+18" firebase_database_web: dependency: transitive description: name: firebase_database_web - sha256: "8414131490173e20b165ccbc03f2ff141d7b0f2999edb9ea48d8d77249f93e9f" + sha256: "383bf00aa419d283818b343845daef1b3e897fab48575ff8d93d89556ceda1cf" + url: "https://pub.dev" + source: hosted + version: "0.2.1+20" + float_column: + dependency: transitive + description: + name: float_column + sha256: "493bef32951f2fc927d7928a777f9ff73460d2f3bc620f191b84b73f27954f69" url: "https://pub.dev" source: hosted - version: "0.2.1+19" + version: "1.4.1" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_dotenv: + dependency: "direct main" + description: + name: flutter_dotenv + sha256: d9283d92059a22e9834bc0a31336658ffba77089fb6f3cc36751f1fc7c6661a3 + url: "https://pub.dev" + source: hosted + version: "5.0.2" flutter_lints: dependency: "direct dev" description: @@ -206,6 +279,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b" + url: "https://pub.dev" + source: hosted + version: "2.0.7" flutter_svg: dependency: "direct main" description: @@ -224,6 +305,14 @@ packages: description: flutter source: sdk version: "0.0.0" + fluttertoast: + dependency: "direct main" + description: + name: fluttertoast + sha256: "774fa28b07f3a82c93596bc137be33189fec578ed3447a93a5a11c93435de394" + url: "https://pub.dev" + source: hosted + version: "8.1.3" google_fonts: dependency: "direct main" description: @@ -248,8 +337,48 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" - intl: + image_picker: + dependency: "direct main" + description: + name: image_picker + sha256: f98d76672d309c8b7030c323b3394669e122d52b307d2bbd8d06bd70f5b2aabe + url: "https://pub.dev" + source: hosted + version: "0.8.6+1" + image_picker_android: dependency: transitive + description: + name: image_picker_android + sha256: "385f12ee9c7288575572c7873a332016ec45ebd092e1c2f6bd421b4a9ad21f1d" + url: "https://pub.dev" + source: hosted + version: "0.8.5+6" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "7d319fb74955ca46d9bf7011497860e3923bb67feebcf068f489311065863899" + url: "https://pub.dev" + source: hosted + version: "2.1.10" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: "8ffb14b43713d7c43fb21299cc18181cc5b39bd3ea1cc427a085c6400fe5aa52" + url: "https://pub.dev" + source: hosted + version: "0.8.6+7" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "7cef2f28f4f2fef99180f636c3d446b4ccbafd6ba0fad2adc9a80c4040f656b8" + url: "https://pub.dev" + source: hosted + version: "2.6.2" + intl: + dependency: "direct main" description: name: intl sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" @@ -356,10 +485,10 @@ packages: dependency: transitive description: name: path_provider_linux - sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 + sha256: "2e32f1640f07caef0d3cb993680f181c79e54a3827b997d5ee221490d131fbd9" url: "https://pub.dev" source: hosted - version: "2.1.7" + version: "2.1.8" path_provider_platform_interface: dependency: transitive description: @@ -416,6 +545,70 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.5" + selectable: + dependency: "direct main" + description: + name: selectable + sha256: a9a79702ef7fd904aa591528a2471e3b2f145cfde308b041297f6d623a13c5ee + url: "https://pub.dev" + source: hosted + version: "0.2.11" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + sha256: "5949029e70abe87f75cfe59d17bf5c397619c4b74a099b10116baeb34786fad9" + url: "https://pub.dev" + source: hosted + version: "2.0.17" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "955e9736a12ba776bdd261cf030232b30eadfcd9c79b32a3250dd4a494e8c8f7" + url: "https://pub.dev" + source: hosted + version: "2.0.15" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "2b55c18636a4edc529fa5cd44c03d3f3100c00513f518c5127c951978efcccd0" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: f8ea038aa6da37090093974ebdcf4397010605fd2ff65c37a66f9d28394cb874 + url: "https://pub.dev" + source: hosted + version: "2.1.3" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: da9431745ede5ece47bc26d5d73a9d3c6936ef6945c101a5aca46f62e52c1cf3 + url: "https://pub.dev" + source: hosted + version: "2.1.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: a4b5bc37fe1b368bbc81f953197d55e12f49d0296e7e412dfe2d2d77d6929958 + url: "https://pub.dev" + source: hosted + version: "2.0.4" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "5eaf05ae77658d3521d0e993ede1af962d4b326cd2153d312df716dc250f00c9" + url: "https://pub.dev" + source: hosted + version: "2.1.3" sky_engine: dependency: transitive description: flutter @@ -477,6 +670,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + url_launcher: + dependency: transitive + description: + name: url_launcher + sha256: e8f2efc804810c0f2f5b485f49e7942179f56eabcfe81dce3387fec4bb55876b + url: "https://pub.dev" + source: hosted + version: "6.1.9" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "3e2f6dfd2c7d9cd123296cab8ef66cfc2c1a13f5845f42c7a0f365690a8a7dd1" + url: "https://pub.dev" + source: hosted + version: "6.0.23" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "0a5af0aefdd8cf820dd739886efb1637f1f24489900204f50984634c07a54815" + url: "https://pub.dev" + source: hosted + version: "6.1.0" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "318c42cba924e18180c029be69caf0a1a710191b9ec49bb42b5998fdcccee3cc" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "41988b55570df53b3dd2a7fc90c76756a963de6a8c5f8e113330cb35992e2094" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "4eae912628763eb48fc214522e58e942fd16ce195407dbf45638239523c759a6" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "44d79408ce9f07052095ef1f9a693c258d6373dc3944249374e30eff7219ccb0" + url: "https://pub.dev" + source: hosted + version: "2.0.14" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: b6217370f8eb1fd85c8890c539f5a639a01ab209a36db82c921ebeacefc7a615 + url: "https://pub.dev" + source: hosted + version: "3.0.3" vector_math: dependency: transitive description: @@ -513,10 +770,10 @@ packages: dependency: transitive description: name: xdg_directories - sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86 + sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 url: "https://pub.dev" source: hosted - version: "0.2.0+3" + version: "1.0.0" xml: dependency: transitive description: @@ -527,4 +784,4 @@ packages: version: "6.2.2" sdks: dart: ">=2.19.0 <4.0.0" - flutter: ">=3.0.0" + flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5beb32b..00c9301 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,39 +1,39 @@ name: crudapp description: A new Flutter project. -# The following line prevents the package from being accidentally published to -# pub.dev using `flutter pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev + + +publish_to: 'none' -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -# In Windows, build-name is used as the major, minor, and patch parts -# of the product and file versions while build-number is used as the build suffix. + + + + + + + + + + + + version: 1.0.0+1 environment: sdk: '>=2.19.0 <3.0.0' -# Dependencies specify other packages that your package needs in order to work. -# To automatically upgrade your package dependencies to the latest versions -# consider running `flutter pub upgrade --major-versions`. Alternatively, -# dependencies can be manually updated by changing the version numbers below to -# the latest version available on pub.dev. To see which dependencies have newer -# versions available, run `flutter pub outdated`. + + + + + + dependencies: flutter: sdk: flutter + - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. + + cupertino_icons: ^1.0.2 google_fonts: ^3.0.1 velocity_x: ^3.6.0 @@ -43,56 +43,67 @@ dependencies: firebase_core: ^2.4.1 cloud_firestore: ^4.3.1 firebase_database: ^10.0.9 + intl: ^0.17.0 + dob_input_field: ^2.0.0 + fluttertoast: ^8.1.3 + image_picker: ^0.8.6+1 + email_auth: ^1.0.0 + chat_gpt_sdk: + git: + url: https://github.com/iampawan/Flutter-ChatGPT.git + flutter_dotenv: ^5.0.2 + selectable: ^0.2.11 + clipboard: ^0.1.3 + dev_dependencies: flutter_test: sdk: flutter - - # The "flutter_lints" package below contains a set of recommended lints to - # encourage good coding practices. The lint set provided by the package is - # activated in the `analysis_options.yaml` file located at the root of your - # package. See that file for information about deactivating specific lint - # rules and activating additional ones. + + + + + flutter_lints: ^2.0.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec + + -# The following section is specific to Flutter packages. + flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. + + + uses-material-design: true - # To add assets to your application, add an assets section, like this: + assets: - assets/Images/ - - assets/Files/ + - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware + + - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages + + - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages + + + + + + + + + + + + + + + + + + +