mirror of
https://github.com/Uttkarsh-raj/Plannerly.git
synced 2025-11-29 21:57:34 +02:00
added signup and login page+ signup block
This commit is contained in:
BIN
Frontend/plannerly/assets/images/logo_black_bg.png
Normal file
BIN
Frontend/plannerly/assets/images/logo_black_bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 422 KiB |
BIN
Frontend/plannerly/assets/images/logo_transparent.png
Normal file
BIN
Frontend/plannerly/assets/images/logo_transparent.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
13
Frontend/plannerly/lib/bloc/signup/signup_bloc.dart
Normal file
13
Frontend/plannerly/lib/bloc/signup/signup_bloc.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
part 'signup_event.dart';
|
||||
part 'signup_state.dart';
|
||||
|
||||
class SignupBloc extends Bloc<SignupEvent, SignupState> {
|
||||
SignupBloc() : super(SignupInitial()) {
|
||||
on<SignupEvent>((event, emit) {
|
||||
// TODO: implement event handler
|
||||
});
|
||||
}
|
||||
}
|
||||
4
Frontend/plannerly/lib/bloc/signup/signup_event.dart
Normal file
4
Frontend/plannerly/lib/bloc/signup/signup_event.dart
Normal file
@@ -0,0 +1,4 @@
|
||||
part of 'signup_bloc.dart';
|
||||
|
||||
@immutable
|
||||
sealed class SignupEvent {}
|
||||
26
Frontend/plannerly/lib/bloc/signup/signup_state.dart
Normal file
26
Frontend/plannerly/lib/bloc/signup/signup_state.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
part of 'signup_bloc.dart';
|
||||
|
||||
@immutable
|
||||
sealed class SignupState {}
|
||||
|
||||
abstract class SignupActionState extends SignupState {}
|
||||
|
||||
final class SignupInitial extends SignupState {}
|
||||
|
||||
class SignupLoading extends SignupState {}
|
||||
|
||||
class SignupLoadedSuccess extends SignupState {}
|
||||
|
||||
class SignupLoadedError extends SignupState {}
|
||||
|
||||
class SignupButtonClicked extends SignupActionState {}
|
||||
|
||||
class SignupPageLoginButtonClicked extends SignupActionState {}
|
||||
|
||||
class SignupPageError extends SignupActionState {
|
||||
String errorMessage;
|
||||
SignupPageError({
|
||||
required this.errorMessage,
|
||||
});
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:plannerly/screens/home/home.dart';
|
||||
import 'package:plannerly/screens/signup/signup.dart';
|
||||
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
@@ -18,7 +19,7 @@ class MyApp extends StatelessWidget {
|
||||
darkTheme: ThemeData.dark(),
|
||||
themeMode: ThemeMode.dark,
|
||||
debugShowCheckedModeBanner: false,
|
||||
home: const HomeScreen(),
|
||||
home: const SignUpPage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'dart:convert';
|
||||
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
class TaskModel {
|
||||
final String taskId;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
|
||||
class User {
|
||||
// ID primitive.ObjectID `bson:"_id"`
|
||||
// First_name *string `json:"first_name" validate:"required,min=2,max=100"`
|
||||
@@ -16,4 +18,68 @@ class User {
|
||||
String? token;
|
||||
String? phone;
|
||||
String? userId;
|
||||
User({
|
||||
this.firstName,
|
||||
this.lastName,
|
||||
this.email,
|
||||
this.token,
|
||||
this.phone,
|
||||
this.userId,
|
||||
});
|
||||
|
||||
User copyWith({
|
||||
String? firstName,
|
||||
String? lastName,
|
||||
String? email,
|
||||
String? token,
|
||||
String? phone,
|
||||
String? userId,
|
||||
}) {
|
||||
return User(
|
||||
firstName: firstName ?? this.firstName,
|
||||
lastName: lastName ?? this.lastName,
|
||||
email: email ?? this.email,
|
||||
token: token ?? this.token,
|
||||
phone: phone ?? this.phone,
|
||||
userId: userId ?? this.userId,
|
||||
);
|
||||
}
|
||||
|
||||
User fromJson(dynamic json) {
|
||||
return User(
|
||||
firstName: json["first_name"],
|
||||
lastName: json["last_name"],
|
||||
email: json["email"],
|
||||
token: json["token"],
|
||||
phone: json["phone"],
|
||||
userId: json["user_id"],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'User(firstName: $firstName, lastName: $lastName, email: $email, token: $token, phone: $phone, userId: $userId)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(covariant User other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other.firstName == firstName &&
|
||||
other.lastName == lastName &&
|
||||
other.email == email &&
|
||||
other.token == token &&
|
||||
other.phone == phone &&
|
||||
other.userId == userId;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return firstName.hashCode ^
|
||||
lastName.hashCode ^
|
||||
email.hashCode ^
|
||||
token.hashCode ^
|
||||
phone.hashCode ^
|
||||
userId.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:plannerly/screens/home/home_loading.dart';
|
||||
import 'package:plannerly/screens/regular_tasks/regular_tasks_page.dart';
|
||||
import 'package:plannerly/screens/urgent_tasks/urgent_tasks_page.dart';
|
||||
import 'package:plannerly/screens/widgets/form_field.dart';
|
||||
@@ -115,13 +116,13 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TaskFormField(
|
||||
title: "Title",
|
||||
title: "Title :",
|
||||
hint: "Title",
|
||||
controller: titleContr,
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
TaskFormField(
|
||||
title: "Description",
|
||||
title: "Description :",
|
||||
hint: "Description",
|
||||
controller: descContr,
|
||||
height: size.height * 0.16,
|
||||
@@ -129,19 +130,19 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
TaskFormField(
|
||||
title: "Date",
|
||||
title: "Date :",
|
||||
hint: "DD/MM/YYYY",
|
||||
controller: dateContr,
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
TaskFormField(
|
||||
title: "Time",
|
||||
title: "Time :",
|
||||
hint: "HH:MM:SS",
|
||||
controller: timeContr,
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
TaskFormField(
|
||||
title: "Urgent",
|
||||
title: "Urgent :",
|
||||
hint: "True/False",
|
||||
controller: urgContr,
|
||||
),
|
||||
@@ -212,10 +213,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
builder: (context, state) {
|
||||
switch (state.runtimeType) {
|
||||
case HomeLoadingState:
|
||||
return const Scaffold(
|
||||
backgroundColor: AppColors.backgroundDark,
|
||||
body: Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
return const HomeLoading();
|
||||
case HomeLoadedSuccessState:
|
||||
final successState = state as HomeLoadedSuccessState;
|
||||
return Scaffold(
|
||||
|
||||
44
Frontend/plannerly/lib/screens/home/home_loading.dart
Normal file
44
Frontend/plannerly/lib/screens/home/home_loading.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:loading_animation_widget/loading_animation_widget.dart';
|
||||
import 'package:plannerly/utils/colors/colors.dart';
|
||||
|
||||
class HomeLoading extends StatelessWidget {
|
||||
const HomeLoading({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.backgroundDark,
|
||||
body: Center(
|
||||
child: Container(
|
||||
height: size.height * 0.16,
|
||||
width: size.width * 0.5,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
color: AppColors.backgroundLight),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
children: [
|
||||
const Text(
|
||||
'Please wait...!!',
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 19,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
LoadingAnimationWidget.fourRotatingDots(
|
||||
color: AppColors.buttonBlue,
|
||||
size: 50,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
131
Frontend/plannerly/lib/screens/login/login.dart
Normal file
131
Frontend/plannerly/lib/screens/login/login.dart
Normal file
@@ -0,0 +1,131 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:plannerly/screens/widgets/form_field.dart';
|
||||
import 'package:plannerly/utils/colors/colors.dart';
|
||||
|
||||
class LoginPage extends StatefulWidget {
|
||||
const LoginPage({super.key});
|
||||
|
||||
@override
|
||||
State<LoginPage> createState() => _LoginPageState();
|
||||
}
|
||||
|
||||
class _LoginPageState extends State<LoginPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
TextEditingController userName = TextEditingController();
|
||||
TextEditingController pass = TextEditingController();
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.backgroundDark,
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Center(
|
||||
child: Text(
|
||||
"Welcome to Plannerly !!",
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const Center(
|
||||
child: Text(
|
||||
// "Let's get your things planned.",
|
||||
"Planning Your Way to Productivity.",
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w300,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Image.asset(
|
||||
'assets/images/logo_transparent.png',
|
||||
scale: 1.8,
|
||||
),
|
||||
SizedBox(
|
||||
width: size.width * 0.8,
|
||||
child: Column(
|
||||
children: [
|
||||
TaskFormField(
|
||||
title: '',
|
||||
hint: 'Username',
|
||||
controller: userName,
|
||||
),
|
||||
TaskFormField(
|
||||
title: '',
|
||||
hint: 'Password',
|
||||
controller: pass,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: size.height * 0.05),
|
||||
Center(
|
||||
child: GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
width: size.width * 0.7,
|
||||
height: size.height * 0.07,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.buttonBlue,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: const Center(
|
||||
child: Text(
|
||||
"Login",
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
"Don't have an account?",
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w300,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
child: const Center(
|
||||
child: Text(
|
||||
"Sign-up",
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
color: AppColors.buttonBlue,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:plannerly/bloc/home/home_bloc.dart';
|
||||
import 'package:plannerly/screens/home/home_loading.dart';
|
||||
import 'package:plannerly/screens/widgets/task.dart';
|
||||
import 'package:plannerly/utils/colors/colors.dart';
|
||||
|
||||
@@ -34,10 +35,7 @@ class _RegularTasksState extends State<RegularTasks> {
|
||||
builder: (context, state) {
|
||||
switch (state.runtimeType) {
|
||||
case HomeLoadingState:
|
||||
return const Scaffold(
|
||||
backgroundColor: AppColors.backgroundDark,
|
||||
body: Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
return const HomeLoading();
|
||||
case HomeLoadedSuccessState:
|
||||
final successState = state as HomeLoadedSuccessState;
|
||||
return Scaffold(
|
||||
|
||||
152
Frontend/plannerly/lib/screens/signup/signup.dart
Normal file
152
Frontend/plannerly/lib/screens/signup/signup.dart
Normal file
@@ -0,0 +1,152 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:plannerly/screens/widgets/form_field.dart';
|
||||
import 'package:plannerly/utils/colors/colors.dart';
|
||||
|
||||
class SignUpPage extends StatefulWidget {
|
||||
const SignUpPage({super.key});
|
||||
|
||||
@override
|
||||
State<SignUpPage> createState() => _SignUpPageState();
|
||||
}
|
||||
|
||||
class _SignUpPageState extends State<SignUpPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
TextEditingController fuserName = TextEditingController();
|
||||
TextEditingController luserName = TextEditingController();
|
||||
TextEditingController email = TextEditingController();
|
||||
TextEditingController phone = TextEditingController();
|
||||
TextEditingController pass = TextEditingController();
|
||||
return Scaffold(
|
||||
backgroundColor: AppColors.backgroundDark,
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
// SizedBox(height: size.height * 0.12),
|
||||
Image.asset(
|
||||
'assets/images/logo_transparent.png',
|
||||
scale: 3.2,
|
||||
),
|
||||
const Center(
|
||||
child: Text(
|
||||
"Welcome to Plannerly !!",
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const Center(
|
||||
child: Text(
|
||||
// "Let's get your things planned.",
|
||||
"Planning Your Way to Productivity.",
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w300,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
SizedBox(
|
||||
width: size.width * 0.8,
|
||||
child: Column(
|
||||
children: [
|
||||
TaskFormField(
|
||||
title: '',
|
||||
hint: 'First-name',
|
||||
controller: fuserName,
|
||||
),
|
||||
TaskFormField(
|
||||
title: '',
|
||||
hint: 'Last-name',
|
||||
controller: luserName,
|
||||
),
|
||||
TaskFormField(
|
||||
title: '',
|
||||
hint: 'Phone',
|
||||
controller: phone,
|
||||
),
|
||||
TaskFormField(
|
||||
title: '',
|
||||
hint: 'Email',
|
||||
controller: email,
|
||||
),
|
||||
TaskFormField(
|
||||
title: '',
|
||||
hint: 'Password',
|
||||
controller: pass,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: size.height * 0.05),
|
||||
Center(
|
||||
child: GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
width: size.width * 0.7,
|
||||
height: size.height * 0.07,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.buttonBlue,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: const Center(
|
||||
child: Text(
|
||||
"Sign-Up",
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Text(
|
||||
"Already have an account?",
|
||||
style: TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w300,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
child: const Center(
|
||||
child: Text(
|
||||
"Login",
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
color: AppColors.buttonBlue,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:plannerly/bloc/home/home_bloc.dart';
|
||||
import 'package:plannerly/screens/home/home_loading.dart';
|
||||
import 'package:plannerly/screens/widgets/task.dart';
|
||||
import 'package:plannerly/utils/colors/colors.dart';
|
||||
|
||||
@@ -34,10 +35,7 @@ class _UrgentTasksState extends State<UrgentTasks> {
|
||||
builder: (context, state) {
|
||||
switch (state.runtimeType) {
|
||||
case HomeLoadingState:
|
||||
return const Scaffold(
|
||||
backgroundColor: AppColors.backgroundDark,
|
||||
body: Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
return const HomeLoading();
|
||||
case HomeLoadedSuccessState:
|
||||
final successState = state as HomeLoadedSuccessState;
|
||||
return Scaffold(
|
||||
|
||||
@@ -27,7 +27,7 @@ class _TaskFormFieldState extends State<TaskFormField> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"${widget.title} : ",
|
||||
"${widget.title} ",
|
||||
style: const TextStyle(
|
||||
color: AppColors.white,
|
||||
fontSize: 20,
|
||||
|
||||
@@ -3,4 +3,4 @@ var userId = "653a2f71e2330ac369e93c9b";
|
||||
// var baseUrl = "http://192.168.2.52:8000";
|
||||
var baseUrl = "https://go-plannerly-api.onrender.com";
|
||||
var token =
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJFbWFpbCI6ImpvaG4uZG9lQGdtYWlsLmNvbSIsIkZpcnN0X25hbWUiOiJKb2huIiwiTGFzdF9uYW1lIjoiRG9lIiwiVWlkIjoiNjUzYTJmNzFlMjMzMGFjMzY5ZTkzYzliIiwiZXhwIjoxNjk5Mjc3MTYwfQ.xvzZ3bdzAagcorXju4cR8o3M51ZC0ZILbMxQmnYG4DE";
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJFbWFpbCI6ImpvaG4uZG9lQGdtYWlsLmNvbSIsIkZpcnN0X25hbWUiOiJKb2huIiwiTGFzdF9uYW1lIjoiRG9lIiwiVWlkIjoiNjUzYTJmNzFlMjMzMGFjMzY5ZTkzYzliIiwiZXhwIjoxNjk5NDQyMzY1fQ.3RxKBUZWuWwdT-5CtSWA36bR_80Z95GnDHbB0l84ePY";
|
||||
|
||||
@@ -128,6 +128,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
loading_animation_widget:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: loading_animation_widget
|
||||
sha256: "1901682600273a966c34cf44a85fc5355da92a8d08a8a43c11adc4e471993e3a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0+4"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -39,6 +39,7 @@ dependencies:
|
||||
cupertino_icons: ^1.0.2
|
||||
http: ^1.1.0
|
||||
fluttertoast: ^8.2.2
|
||||
loading_animation_widget: ^1.2.0+4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in New Issue
Block a user