1
0
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:
Uttkarsh-raj
2023-11-07 21:26:21 +05:30
parent 4a72553c2c
commit f667caedb5
18 changed files with 460 additions and 22 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View 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
});
}
}

View File

@@ -0,0 +1,4 @@
part of 'signup_bloc.dart';
@immutable
sealed class SignupEvent {}

View 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,
});
}

View File

@@ -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(),
);
}
}

View File

@@ -1,5 +1,3 @@
import 'dart:convert';
// ignore_for_file: public_member_api_docs, sort_constructors_first
class TaskModel {
final String taskId;

View File

@@ -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;
}
}

View File

@@ -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(

View 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,
),
],
),
),
),
),
);
}
}

View 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,
),
),
),
),
],
),
)
],
),
),
),
);
}
}

View File

@@ -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(

View 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,
),
),
),
),
],
),
)
],
),
),
),
),
);
}
}

View File

@@ -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(

View File

@@ -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,

View File

@@ -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";

View File

@@ -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:

View File

@@ -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: