Transcripts
1. Course Introduction: Are you interested in creating a real-world application with
tartar or do you want to impress potential employers with your mobile development skills
and get your dream job, then this course
is just for you. It will teach you how to create a fully functional employee attendance management
system with clutter and supervise with provider as that state
management tool. Supervisor is an open-source
alternative to Firebase and is gaining a lot of popularity among
the tech community. We will start by building a
robust authentication system, enabling employees
to register and login with their email
and password get inches. We will then create a
user-friendly interface, allows employees to easily slide to check-in and
check-out for the day. That current location of the
employee will also be saved so that it is confirmed that
he or she is in darkness. The application will also implement features
that enable employees to view their attendance history for any month of the year, update their personal details, as well as company department, all while maintaining efficient state management
using provider. By the end of the course, you will have a complete
attendance management system that you can use in your own organization
or showcasing your portfolio without
wasting any more time. Let's get started.
2. Create a Flutter Project: Hi, welcome to the very
first video of the course, where we will build an employee attendance
management system with flutter and Superbus. I'm assuming that you already
have knowledge of clutter. And when it comes to supervise, that quiet is are very straightforward and
simple like Firebase. So if you have
knowledge of Firebase, you won't find it difficult. Also, I will be using the provider package as the state management
tool in our project. You should have knowledge
of debt as well. So without wasting
any more time, Let's get started by creating
a new Florida Project. Go to your desired directory
and open up your terminal. Then the command, Flutter. Create employee
attendance center. Obviously you can use any
project name. It's up to you. Then open up your terminal. Sorry, open up your code editor. I will be using VS Code. Then. Ben, your project. Our project is created. Now, it's time we create
a supervised account. Open up your browser
and type supervise.com. So this is the
official page here. Click on sign-in. And obviously, I've been
signing directly because I have already logged in earlier
using my GitHub account, you will definitely
get an option to sign in with your
GitHub account. You just enter your credentials and then you will be
sent to this page. Here. Simply click on Create Project. Also remember, to
create a new project, you need to have
an organization. So I have namely travel. You will get an option there
to just simply name it. Now here the project name
will be employee attendance. I will just generate
a random password. Yet, choose your nearest reason. And pricing plan will be free. After that time it is
setting up project. Simply bring out your VS Code. And here in the new terminal, I will simply write
that combine data. Bob, add super ways, louder and louder, dot ENV. These are the packages
which are required. You can also go to bob dot dev and check
out these packages. To pop is flutter is used to interact with does supervise. And this dot ENV is used so that our passwords
doesn't get compromised. We won't write the
password directly in the main file or the
Screens fine, like that. We'll just go and check the
Pub spec dot YAML and see. We have this two. We have this to install. Now. In the root
directory of our app. Just create a file
and name it dot ENV. Make sure you are not
creating this inside that. You have to create in
the root directory. And here we will store the
Superbus credentials like evaulate super base
URL is equal to this and super ways k is equal to. Then. Go to the dashboard here, click on Projects setting, then API. And here you can
see the URL is copy it and paste it here. And then copy that. And on public key and
paste it in that key. That's it. See you have directly copy
and pasted the details here. After that. In that pub spec dot YAML file, we have to mention that dot ENV file in
the asset section. So go below here. There's just uncomment it. Remember this Pub
spec dot YAML file is very case sensitive, so any extra space or
tab will give at a C, you have to be very
careful like this, just like dot ENV and save it. Okay, so that's it
for this video. In the next video, I will initialize our Superbus and run the
application. Thank you.
3. Initialize Supabase Client: Hi, let's continue. So since we have
installed dependencies, we have to configure
the Android as well. So go to Android, then app. And inside here you have
the build-up Gradle file. Here. First. You have this bile SDK version. Make it 33, like this. Then you have minimum
minimum SDK version. Yeah, yeah, here. Make it 19. And also enable multi-decade. With this line. If you already have
configured Firebase, then you know that these
are required every time. And also I will just
go to Android source, main Android
manifest, and change the Android label to ban. So this will be the app name, or you can say this is the employee management system
for a company named Fang. That's okay. Then we have to initialize that supervise client
inside our main function. So go to main here. Yeah, just make it a sink. Then like rigids, they're
binding and show initialized. Then first load ENV files. I will right away. And I will first import dot ENV as well as I will import
Superbus flutter like this. And here I will simply
write that command dot ENV dot load. So it will load that
dot ENV file of hours. And then I will
initialize supervise. First, I will just get dow URL in the key in
a separate variable here is I will just
write dot ENV, dot ENV. Here. We have to
write the key name. If you know that. This is the key for the data. So I will just write
this and it can be null. So I will just make
sure if it's null, then give it the value
of an empty string. Then we have the
supervisor is key. Here. It was about whiskey. After that, I will
initialize with the code supervise,
not initialize. Then here we have
to give the URL, which is superbly cURL. Anon key will be super risky. That's it. This is how
we initialize Superbus. This is very straightforward. Now after that, we will
structure our project. I will just close
this and Android. And inside lib, we will
structure our project into folders instead of writing
everything at one pile. So create a new folder
called screens inside lib. Then create another
folder called Constance. Another folder, you
tills, therefore models. And finally, we have services. So this is a better way of
writing code. And insights. Greens, create a file. Login screen dot, dot. Let's import material and create a stateful
widget for now. Login screen. Yeah, I will return a scaffold. In that body. It was simply write. It is working. And in domain dot dot. Simply. First I will remove this comments and remove
everything from here. That is from class homepage. Remove everything and give the login screen as
a value to the home. Save. All. After that, I will start my pixel
five Android emulator. You can connect your
physical device as well. It's up to you. And I will try to run
that application. Now let's see if we runs
or there is any editor. This is the first time, so it might take some time. So till then, if you want, you can just go to the
Superbus flirted darks. Here. And here. You can, you can see lot of praise or you can understand if you have
no idea about Superbus. Let's see. What don't we have
any other dogs? Yeah. Here you have all the queries, how to fetch data, insert, how to login, how to create storage, and also this, this URL
will be helpful to you. This will come handy. Make sure if you have free time, you read everything here. I have some license and all
which has to be accepted. That is why it is
taking some time. That's fine. We can wait. See dapp. And now the screen, it is working, is there. That means our app is
working perfectly. I will just change
here this title to employee attendance and
debug banner to false. That's it. That's
it for this video. In the next video, we will work on that
login screen UI. Thank you.
4. Create a Login Screen: Hi, welcome back. So in this video we will start working on the
login screen UI. So this is the screen where employees can login
into their company, which I have named
this Pang, f, a, and g. So let's get started. So first of all, inside that will create variables to get width
and height of the device. So simply, double. Screen width is equal to media query dot off
contacts should be, they're not of contacts. Dot size, dot width. And similarly, copied, pasted. It will always green height. And this will be high. Now, let's start. Let's start on wi. In that body, I will
use a column that children's first
havoc container. Height of the
container will base green height divided by three. Weight of the container
will be screen width. Let's give some declaration. Const box, decoration,
color, colors, red, accent. Then border. Radius will be border
radius, circular. It should be it should be only. Then inside here, right? Bottom right. It will be radius circular 70. Okay? And inside that container we have that child property. It will, again via column I will give a random icon and
first it will remain exists alignment main
excellent Mendota center so that the child will be
sent out of this container. And then we have that children children
will be of ponds to value will be I can start QR code scanner. You can QR code or you
can give whatever I want. Les dot white, size a day. Then give us size
rocks of height, dy, and then give it
text of company name. I will do it. Fang style. Textile. Bonds size will be 25. Colors dot white. Font weight, font-weight, bold. Save everything.
Let's check out. See, it is looking descent. We have this bottom radius here. This is that container
galleries red X and you can change the color
according to your need. Then we have in that child
in a column that I can end up text which is in the center since we have given main
axis alignment dot center. Now after that, we have
to create two texts, anything controller
for that text fields. For them, login purpose. So let's go inside that class here and write final
text editing controller. E-mail control able to
text editing controller. Similarly, we have the
text editing controller for password as well. The password controller is that they'll do anything controller. Then inside column widget. Here, create another column
widget with some padding. So below, Let's see. We have this column
widget, it ends here. Then give some spacing size, box height 50 than depth. By adding widget. I will give the padding is 20. And I love the padding
will be column. Now we have that children. In that children will
have that text field. Declaration, Const
input declaration. Label will be text. Employee, e-mail, ID. Fix. I can I can I can start person. You can write person, you can write email,
whatever you want. Border, outline input border. Then we have the controller Option outside the declaration and we will give it
E-mail controller. And after this text
field, give some spacing. Size, box height 20. Let's save everything. You can see the code and now see we have the employee
e-mail ID like this. So that's it for this video. In the next video, we will
complete this login screen, as well as create
the register screen. Thank you.
5. Create a Register Screen: Let's continue working
on the login screen. Below this size box. Create another text. You can simply copy this text, will paste it. Here. It will be password. I can Solvay, I can start luck. Controller will be
password controller and obscured text will be true. That is, whatever we type shouldn't be shown
to anyone else. It will come as stars. Below this text will
give some spacing. Sized box, height 30. And then let's have it button. Give it a size box. Its height will be 60, which will be double
dot infinity. Child will be elevated button. That text written in the
button will be login. And we will give some tech
styling to it as well. Font size 20. Make it const. Then give some style to the
elevated button as well. So here, like elevated ten dot style from this is how you give
style to elevated button. Background color will be
colors that red accent. And shape will be rounded. Rectangular border, border
radius, border-radius. Circular today. This is just, it should be at the
end of the argument. That's it. Let's check it out. See, the button is also
looking good. Now it's time. We create another
screen for registering. So inside screen simply rate
registered screen dot dot. So obviously this
is the page where new employees can
register, copy, and paste that code from
employee screen here. Then we'll just
first of all change the name to the screen. Okay? Now here in the scaffold, we will have an MBA so that we can show that
back button as well. Let's simply write AB bar, background color colors, the
red accent, elevation zero. And I will just change the height to adjust
with the app bar. And finally, in the button, I will write here register. That's it. Only
these three changes. Save. Now we have the register
screen as well. Now let's navigate to register screen from the login screen. So go to login
screen dot dot file. Here. Below this sized box. I will give some spacing
with this size box D. And let's create a
text button which will navigate to which will navigate
to that register screen. So I will just add text. Are you a new employee
registered here? And in the on-premise
evaulate, navigate their Bush. I hope you already
know these commands. These are all the basics
of how to navigate the now all we have to write text here and
we will send to that register screen like this. And this is a const. C. Save everything. Now we have the login and if
I click on register here, see we have the register
screen as well. And here in the app bar, we have the back button, which we can again go
to the login screen. So that's it for this video, we have successfully created the UI for login and register. See you in the next session.
6. Create Auth Service Class: Hi, welcome back. So now it's time we
start working with data, or you can say state. And for that purpose, we will be using provider as
that state management tool. So now let's install the provider package
in that terminal. Simply write letter ad provider. That's it. You can
also go to bob.gov website and get that
pervaded from there as well. Just check. Yes, we have the provider. Now, let's first
create a utils class. So inside the utils folder, create a new file. Dot dot. We will create a static
function to show the snack bar. Since this will be
used many times. That is why I am creating
a separate method for it. Simply import material
than the glass. You tills that thick, wide. So snack bar. We will accept the message, the bell context, and an
optional value of color, which can be null. Since this is optional. Then we will write scaphoid, messenger off contexts,
dot show snack bar. So this, this code
is from flatter. Remember, snack bar. Now content, I will give text
and send a message here. And within this snack bar, within this snake, but we
have that background color. That will be color. That's it. So if it is null, then it will get to
its default color. Now, we have that
utils function here. Now let's create our
art service class. Now things will get interesting. Insights. Services, right? Surveys, dark, dark. Here we will write
all the methods related to authentication. So let's first of all
material package, then import, supervise package. Then create the
class art surveys, which will extend, change, notify or since we will
be using provider. So first thing I will create an instance of Superbus client. So byways gland supervise is equal to super base
dot instance dot client. This is just creating
an instance. Then I will create is
loading, variable. Is loading. I have created a
private variable for each loading and
then create getter and setter so that users outside this class cannot access
this value directly. They have to go through this, so they cannot
change it directly. Odd service dot this, They cannot do this. They have to use
this method set. Method. Set is loading. We will send a bool value. It will be is loading
is equal to value. And notify listeners
so that anyone who is listening to this
odd service will refresh. So that's it. For this video. In
the next video, we will work on
different methods. Thank you.
7. Method to Register Employee: Hi, welcome back. So now let's create a method to allow an employee
to register an account. In the arts or risk class. A future function. Register employee. Like this. We will require thing email, string, password, as well as the bell contexts to
show that snack bar. Then we'll wrap the code
inside the try catch block. That try first I will do is set, is loading to true. It is. I will use this setter method. Then I will check if
E-mail is equal to empty. Our password is equal to Md. Then throw an error. Whales are required. And if not, then I will write
the query to sign them. That is that datatype, which is the return, is
called the art response. Then I will add await Superbus instance is
that variable dot, dot sign up like this. And here we have to send that e-mail
and the password. And after this, we will show
utils dot show snack bar. Message will be success. You can now log in and color will be
colors dark green. Then I will simply write, navigate the third dot, pop. And set is loading to false. So this is the code. And what if there is some adder? First off, what I will do, a set is loading to false. Then I will show that snack
bar utils dot show snack bar. Message will be e dot ToString. Contexts will be contexts, but color will be red. Okay? So this was the
method for register. And I will just go to
the documentation here. And I will show you this line
that is signing a user C, you get Dakota, here
are the response, supervise or that
sign-in with password. This is the sign in study. We have that create a new
user and C dot sign-up. So this is very straightforward. It, you get the user from
the response as well. So that's it for this video. In the next video, we
will write the method to login as well as sign out and Q.
8. Method to Login and Sign out: Hi, let's continue
with our methods. And below this
register function, Let's create another
function, or my third, you can say for login,
employ this future. Now again, employ here also. We will ask or the e-mail buzzword,
bill contexts. And that code is
pretty much similar. What you can do is
copy this code, paste it here, and then here we have is loading to
true art response. This will be sine
in weight password. And I don't have to
show our navigate here. Simply set is loading to false. And suppose we have any error. It will catch here. I'll cave. Below
this function grid. Another function
calls for sign-out. This is very straightforward,
like a weight. So purveys dot art, sign out. And we will notify
the listeners. We will also create
a getter to get the user that this user get
current user from Superbus. Simply way light supervise
that art, dot current user. Like this. That's it. This will get
if user is signing or not. Now, we have the
provider here, right? We have to declare our
provider in that main dot, dots so that the flatter nose that we have provided
in our application. So simply here with rigid
called multi provider. The provider, since we will have multiple
providers later on. Here. Here, simply write, notify your provider. Then create. And we have the bus
stop context here. And write odd service. Simply like this. That's it. This is how you declare providers in a
flutter application. So that's it for this video. In the next video, we will assign those
methods to the UI. Thank you.
9. Assign Methods to UI: Hi. So now it's time we assign
that registered as well as the login function to our UI. So go to register screen. In that register button. I will be wrapping this
elevated but then inside consumer so that we can access properties and
methods from AAD service. And I will be using this way so that not that complete widget, that is the bill function will not rebuild again and again only this
section we'll rebuild. So let's write like
consumer, consumer. Here we have to mention
what provider we are using. Then we have the builder. This will have gone decks or
service provider instance. This jail is not use. Here. We have to
return this size box. Just got paste. Give semicolon. Here. This is four. Okay, we have to remove
this only, that's it. So we have acted. Also, we will show a loading, loading indicator
conditionally. Here. In that child, I will write odd service provider
dot is loading. If it is true, then show in the center child and it's cooler progress
indicator like this. That is if loading is true, Show circular
progress indicator. And if not, then in
the on-premise we will write odd service provider,
registered employee. Here we have the right
e-mail controller dot text in that password. Password controller dot text. And here I will just
give a dream as well. What if there is
some extra space? Frame? K? So this consumer is the
concept of provider. So you should have known
this concept at least. Then. Similarly go
to login screen. Here. We have this 1 s, I guess. Yeah. Yes. Okay. Yep. Here. This size boxed with that consumer
direct service provider. Then we have the builder. It has gone texts instance of art service class that is lightly you can
name it anything. And we have the chai and then simply return this login button. This child. Similarly here in that child we will
give it conditionally. The taste. Odd service provided is loading. Then const center, circular progress
indicator. Like this. And in the press we will write odd service provider,
dot login employee. I've tried email controller, dot text, password
controller dot txt. And also here again, you can do the trim stuff. That's hit. Save everything. Now. Go to them. Superbus dashboard. Here. Econ authentication. In that providers, as you can see, email
is enabled by default. I will just disable that confirm e-mail because we have to verify each email
before sign-up. Later on if you want, you can enable it. Now, click on Save. So now email is there, like now we have no users. Let's finally check whether
it is working or not. Now, if I give something and I write
12345 and click on Login, see we have the odd exception,
invalid login credentials. So that is this email and password are not
registered like now. I will register it. Use whatever e-mail you want. Then password,
click on Register. K, success. You can now log in. See. Now if I write that password, it should have. Obviously that now I
am not doing anything. We we won't be sent to
any screen right now, obviously, because we're not
listening to the changes. But if I go there and reload, see, we have the e-mail
registered successfully. So that's it for this video. I hope you have learned
and understood till now. See you in the next session. Thank you.
10. Creating User Model and Db Tables: Hi, welcome back. So now we will create a
model for the user data. So inside models folder, create a new file called
User model dot dot. Now, all these data we will store in the database
after the user registered. So right now when
we're instead only, we can see that data inside
the authentication section. But what if we want the
name of the employee or the Department of them employ those data we have to
store in the database. So let's say Glass. User model. Data, which will look coming
will be binary, string ID, then fine string, e-mail, final string name, vinyl. Make it large. Final int department. Because we will create another table for department
and on list tool, the ID that is this will be a foreign key to the primary key if you know the concept of SQL and then binary string, employee ID is the
ID which we created. That is, this will
be unique idea. Let's create a constructor. Then the required id, required. These don't email. Acquired this name
and department. Since it's in a
liberal we're not writing that required required. There's dot employee ID. Now create a factory method to convert that JSON data which is coming from the super
base to this model. So assembly factory
user model for the user model dot Rahm, Jason, map, string dynamic data, and return a user model. And here you have to write data. Id is GAAP bit based IT
department is left. This will be email. This will be named. These names or column names, which we will create in that Superbus
department employee ID. Okay, save all these things. This is not required. Now, let's create a table
further department. Let's go to a browser. Go to your browser. Then go to Table Editor. Then create a new table. Name. Departments. Then don't enable IRLS for now. And we also don't need
realtime for this data. Simply create a column of title. Make it text. That's it. Save it. And then insert some data here. So here, first will
be sales, then, and then the department,
id department, then marketing, and HR, then finances there. These are just the
departments in a company that's AND operation. So I have entered data. Suppose if you want,
you can create another app for the
admin of the company. He can enter these datas
from his admin portal. It's up to you. Now we have the departments. They will create another
table called employees. Employees. Yet again, remove
the RLS for now. And then. This id will be a foreign key to the art user's Id. This, so this id will be same as the user's authenticated
idea. Just save it. Then, give it a name. Make it text. Then we have that email. Give it text. Then give a row
for column for department. It will be a foreign key for the departments
ID like this. And then next we have
the employee ID. Id. This will with text as well. So we have two foreign keys, department and the id. This is primarily
as well. Save it. I hope you understand that these tables are
same as this one. These data IDE may lean
department employee ID. Now finally, in their constants, they will create the file
name constants dot dot. We will write that they will name aesthetic variables here, so it is easy to use them
later on anywhere in the application without
any typing mistake. Like glass, constants. That take gone. Employee table is
equal to employees. And that **** gone st department is equal
to two departments. That's it. We have done
a lot in this video. See you in the next session.
11. Creating Database Service Class: Hi, welcome back. In this video, we will work on creating a database
service class. So earlier we have
the art surveys. It's time we create another
file inside services and name it DV, surveys dot dot. So create a class DB service which will extend
to change modifier, since it's, we will use it, use it as a provider. Then create an instance
of the pelvis client. Supervisor is equal to supervise
dot instance dot client. Okay? Now the first
function we will create is to insert
a new user data. They will limit insert
new user database table we created employees. We have to store this
information there. From user. We will ask or string e-mail ID, that is the art ID. Since here we mentioned that the idea will
be a foreign give. That is the only reason they are inserting
in the database. The command is purveys instance dot from that is which table? Table name is there in that constant start
employee table. Then dot directly
the query is insert. Here we have to send a
map value. That's it. This is the only query needed to create our insert
a new data. Here. Id will be id. Name will be empty
since it's a new user. Email will be email. Then this is new, that is employee ID. This we have to create
a function to generate. We will create it, and then department will be null for now. I hope we have the department, yes, we have the
department there. The user can update his department later on
in the profile section. Now, we have to create a
function to get a random ID. So let's create string, generate random employee ID. Now, we will use the
random function here. This comes from
the math library. Now, what I will, what characters I want is just the name of
the company here. Suppose f, a and g, then capital F, a and G, and then all the
numbers like this. So that means the function will create the ID from
these numbers only, that is from this
character's only. This is, this is
just my preference. You can use all the characters, that is from a to Z.
I'm just using this. Then. I really could write
a function which I myself got from the Internet. List, dot generate, land,
Taiwan, eight characters. Then here, all characters. Random dot, next, int, characters dot length,
and finally at the end dot join,
join like this. So this one Chen I myself grabbed a god
from the Internet. You can also use any other generation
function if you want. This one chain does what? It creates a eight digit random
ID from these characters. Now, call this function here. We have the insert new
user function ready. Now, we will call this insert new function
while registering a new user. So go to AAD service. While here, when we
are registering. Now let's see. We have
final art response here. I will simply write if
responds not equal to null, then that and paste
everything here. First of all, I will do is wait. I have to create an instance of that dv service at that top. By null DB service. The recent. Create an instance so that we can use
the functions. Then here, I will
write below this, above this utils, divi
surveys dot insert new user. You may Lee's email and ID
will be responds dot user ID. This. We have to send the
email and they are tiny. Then we will show a snack bar that shows nearby
here I will just write successfully registered and I don't want the user to again and then his
login credentials. So what I can do is I will call the login
function here, like this. Login employee. I have the email
password and context. And since settler loading
is false here as well. So I will remove this from the function that
there's stuff on Chen. I don't want them
set loading false because it is directly call
inside login employee. Here. I hope you have
understood that I have called this
function here so that the user don't have to enter that email again
after registering. Just imagine here's registered and now again have to go to the login page and again
type the same data login. That's the only reason. Now, since we have
this new provider, I will declare it in
the multi provider. So just go here, copy this line, paste it, and write dv service. That's it. So that's it for this video. Let's continue in the
next session. Thank you.
12. Handle User Auth State: Hi. So we have everything ready. That is the registering
and the login portion. Now, Insights screen, create a home screen so
that the user can navigate to that after
registering successfully. So simply import material, then create a state rigid, name it home screen. Then here simply return a scaffold body centered child. And I will write it home screen. So this is just a
dummy data for now. Just the simple text widget
in the middle of the screen. Now, we have to check, that is when the user
or pins that we have to check whether he's
logged in or not. That is, whether it's a new user has already
logged in before. So we have to show him
the screen that is login page or the home
screen conditionally. For that insight screen, create a new screen
called splash screen. Dot dot. Again import material. Then create a stateless rigid, call this splash screen. Then here in the belt. First of all, I will
call the odd provider. That is, odd surveys is equal
to provider of context. And then the service. Then I will return
file accordingly, this if AAD service dark
current user is equal to null, then to login screen, to the home screen. That's it. I know that previously
by after registering, I also loved in
with the details. So for now I will
call the art surveys dot sign out so that
that session is over. And go to the main dot dot and make the splash screen
as the root screen. Like this. That's it. Let's see, unable to pass. What's the deal here? Okay. Just go to the main.out and splash screen and
comment this out for now. Okay, to notify list again and again.
That is, that isn't. So obviously we won't call this function
here again later on. But now, since we have that
data base section here, we have to go to the authentication
and delete this user because earlier we didn't save the user details
in the database. Delete this user, we
will register again. Now let's bring out our app. Click that again within email. 345. Register. Now let's see
whether we logged in directly or not
successfully registered. And we are directly sent
to the home screen. So that I was talking about. The user doesn't have to login again because it's a good
experience, I believe. So. Now, if I restart, let's see which
page do I see that? I see the login or
directly the home screen. And see if we are
in the home screen. There is no login screen
and all since we're also handling the status
of that user. So thank you. In the next video, we will work on the
home screen UI portion.
13. Work on Home Screen: Hi, welcome back. Now let's start working with creating a bottom
navigation bar. In the home screen, you will see the homeschooling
is right now empty. So let's work on that. Go to home screen. Here. Below the body. Let's create a
bottom nav, nav bar. It will be a container. It is the value. Then the height of
the container is 70. Then give some margin. Const, edge insets
dot only left, 12, right, 12, bottom 24. Then decoration. Give a const box decoration. Then here give it color. Colors dot white. Then border-radius. Border-radius dot
radius, dot circular for t. Then give box
shadow effect as well. It accepts an array and the only value we will give
is box-shadow, then duller. Colors, dark, black,
26, blur radius. Then offset. Offset value will be 22. So just let's see how it looks. See we have this
navigation bar right now, it's just certain container. We will add the values here. They will be icons here. And for that, I will use a library known as
Font Awesome icons. So simply open up the terminal, terminal end right, flatter. Add Font. Awesome letter. So this is the I can name, that is the package
name. Press Enter. You can also go to the dev and search for this
package if you want. This package helps us
to use lots of icons. In this application. We won't be using
that many icons. That is, if you want, you can remove this
later on as well. To make it work, you have to stop the
application since it's a new package and
then rerun it again. I will just close this file. And this is I don't
need these files now. Only the home screen. Okay? What happens? Now
again, working. Now, let's create the icons
inside this container. Here in that child. Simply give it a row. Row. You have children. And in that row, right? Main exists and cross axis
to center, like this. And then we need **** can
say we'll just do it. I can see a list of icon, data, navigation, icons. Then worst I will let
Font Awesome icons, that solid calendar days, then Font Awesome icon, check. And finally, Font Awesome
icon dot solid user. So these are the three
icons which we will use. Here in that children, simply right, give
it a for loop. For int I is equal to zero. I less than navigation icons
dot length I plus plus. Then use this spread operator. And then we will use expanded
child will be center. And then F icon give navigation icon index
that these one-by-one, all the icons will be output
in an expanded region. So now let's check how it looks. If I go see, we have that three I can see at this looking
decent, I believe. Now, obviously nothing
happens if I click on it. We have to work on that. Now, here below the icons, let's simply like int current
index is equal to one. And in that children, we have this expanded. Then this center inside
GestureDetector. In the tab. We will simply write set state. Current index is equal
to I, change the index. And then here we will change that color
according to the index. So we will rate color. If, if I is equal
to current index, then colors that the red
accent colors dark, black, 54. Similarly size. If I is equal to current index, then make it 30 or else 26. Let's see whether it
is working or not. If I click here, see the icon size and the
color, both are changing. Now, you can see we
have three screens. So let's create
those three screens. Inside screens, create
calendar, screen, dot, dot, then attendance,
green dot dot. And finally we have
file green dot dot. Inside everything simply,
let's create a basic screen. It is important material then creates the lender. Screen. Return is scaffold. Body, center, child. The next calendar. Copy everything. Go to Attendance screen based changed their name
to then dance. Green light today. Attendance. And similarly go to profile
screen, paste everything. Changed their name to profile
screen and idea profile. This is just a dummy
screen right now. Finally, add that
these screens in the body of the home
screen so that we can navigate to them with the help of the bottom
navigation bar. So go to home screen here. End up body here, right? Indexed. That stake in there. Then in the index will be current index. And children will
be all the pages. This will be const. Let's write lenders
green as first, then green, then
that profile screen. That's it. Save everything. Check it out. See today attendance. If I click calendar. And if I have if I click the Upload File and since
indexes when it is 01, read the first page is shown is that attendance for today? So everything is
working till now. In the next video, we will work on this
today, then then screen. Thank you.
14. Work on Attendance UI: Hi, welcome back. So now let's start working on this date and then screen UI. So here in the body, Let's start with is
single child ScrollView. In that child will
have a column rigid. And then that children and in that single
child scroll over, I will give some padding guns
and insists that all 20. Now in that children, let's have a text widget that is overlapping inside
the container. Give IT alignment to alignment. Dots centered, left. Then margin, const,
adding sets, not only 32. Then child. Const. Text as welcome. Style. Textile. In the
textile give some color. Colors, not black 54. And font size as 30. Okay, save this. And then below this container, like another container that is here we have the welcome and here we will have
the employee name. It is alignment. Alignment, center left. Then child glanced, text. I'm Louis name. This is just an employee
named dummy light. Now we will show later on text style and just give
it a font size of 25. Now save it. Let's go and check. See, we have the welcome
and employee name here. Then let's continue. Below this container. I will have another container. Copy this one, paste it. Here. There will be margin. As const. Adding sets that only 32. And here the texts will
be two days. That does. And font size will be doing do. And then below this container. And that container,
give it a margin. Const. Adding sets that only 12. But I'm 32. I write 150. Declaration. Const box decoration. The LED colors dot
white, box shadow. We have the box shadow here. Well, there will
be colors that 26. Then blur radius
is then an offset, offset value to two. And below this, that is
below that box-shadow. We have that border radius. Border radius, the
radius dots are cooler. Now say, well, let's see how it looks and see
today's state status and this is looking decent. Now. In the next video, we will work on the
left out UI. Thank you.
15. Implement Slide to Check in: Hi, Let's continue working. So here we had this container. Within this container grid, that child row widget. There will be children. Children here it will write the main axis alignment,
center, alignment, dots. And then within that, children died and
expanded rigid. I hope you know all these widgets because
I'm just creating the UI, nothing else. X bonded. Then here it will
be column vision. Then again in that column, we have the main axis
alignment and cross. Just copy and paste it. And then we have that children. Now here. That's right. It takes widget. That text will check in. Give it some styling. Text style. Font size will be 20, color will be black, 54. Then below this
text size, the box. Wait a day. Child divider, just to give some spacing. And then another text. Now the timing right now
it's just hard coded 930. Then stale. Deck style, font, size
25. You can see it. It is rho inside row. We have this expanded widget. Now. Copy this expanded rigid. And within this row, paste it again like this. And here this will be checkout. And the texture will
be blank like this. And save it. Let's go and check it out. See, it is looking
decent, I believe. Today's status. And like this. And below that
today's state does. You can give some more just
to give some spacing here. That's it. Up again between d. Okay. Now for the check-in, I will use a package. So just write later. Bob, add slide to act. We will use this slide to act package to implement
functionality, to check-in,
check-out and employ. This will look good rather
than just a button. Elevated button is
pressed to check-in. This will look good. I guess. We might have
to stop and rerun. Let's see what happens. But if I go to the pub spec
dot YAML just to check, see, we have the widget
here, sorry that packaging. Now let's work on that. Go to then, then screen. I will close all the pages. Here. At the very top. We have to create a
key for the slide. Rigid, solid global key. Slide action state q0
is equal to global key. Light action state. This case just required
for the widget to work. Now, below, inside that
column we have to write. So that is, we have this
column widget here, go down. Here. We have to give another container is alignment. Alignment center left
child. The next 15. April 2023. Textile. I'm just hard-coding
this information now. And similarly copy it
and paste it again. Here that the x
will be the time. So I will just write Duan
De zero-zero, zero-one PM. And have fun size will be D. Color will be colors dot black. Fifth default. Just
save. And see. This just shows
that latest date. That's it. And this will be
that time, current time. Now it's time we create
the sliding button. Within that column. Just create another
container. Margin. Const, add in sets that only 25. Then child will be a
builder rigid. Like this. Here it will be the context. And then simply return the
slide action like this. And now text will be slayed. To check out. Then textile will be textile. Color. Layers, dark, black, 54. Bonds size will be 18. Then below that style. The outer circle, outer
color will be colors. That white color will be
colors dot the red accent. Key will be key. Finally, on submit. Like this. Here, just right. The Garden State reset. So that does light, that gets to its
original position. So see, we have that slider. It gets to its original position because we are resetting it. But it is looking so nice. And accordingly,
you can just give the padding margin size if you feel there is
left out space here. So you can do these
things later on because you might want to
show some other information, some kind of advertisement here. It's up to you. For me, this functionality
should work. That's it. That's it. For this video. We will keep working and get real data in this fails
in the later videos. Thank you.
16. Function get User Data: Hi, welcome back. Now it's time we create
a function which will fetch the user data from
the employees table showed, so that we can show those
that are here in the screen. Go to DB surveys dot dot file. At the very top. First, create a variable
for user model, which can be null. User model. Then create a function. If future function which will return a user model it
is, we will patch that. It doesn't convert it. Then I get user data. The query is user data
is equal to await. Super Way's dark rum. That is, which table? The table is constants
not employ table. And query dot select. That is, it will select all, but obviously we have to
select only this employee. So we will use equal
which column we have to check the ID column and which
value we have to check. We have to check
superhighways that art. The current user id. That is, since we know
it cannot be null, I have this gave
this exclamation. This query will go to the
employee table and get that data which is
equal to this ID. And this means he will go and check this
ID, this column id. This is very straightforward. Then. And I know that the
data will be single and Lisa will just write single
because there cannot be more than one employer
with the same ID. Then I will write user model is equal to user model from Jason. And I will send that
user data here. And I will also return
the user model. And this is not null. So I hope you have understood
this line of code. So we're getting the data. We are changing the data to a user model and storing
it in this user model, a variable which we have
declared at the top. Now, we will show
that username or the ID instead of the placeholder inside
that and then screen. So here we have this container employee name that I will create
a consumer widget. This is, this comes
from provider. Remember, it will be
listening to which provider, DB, service and Builder. We have context, the service class
instance, and the child. Then return your chair builder. And now, what is the future? The future is dv surveys, dot get user data. So it will send the
user data here. In the Builder, we get the
context and thus snapshot. Now, we know how to
use a future builder. That is, if snapshot has data, then do something else. Return, const, size, box, weight, 60, child, linear
progress indicator. And whatever the user has data. Then we will return this container that is
employee name container. Maybe it'll go return
employee name container. In that text. We will write here snap shot. That is, if it has
the user model, user is equal to snapshot
that dataset because we know the data coming
is a user model type. And here now in that text, I will write if user dot
name not equal to empty, then write user dot name. Wait, Let's see. I hope nothing is wrong. Like the id, like this,
user employee ID. But now let's see. Okay, this cannot be constant. That's it. And let it be const. Now save everything. I hope you have understood
that using the consumer and accessing the service, then calling the
future function. And here are simply
checking that user has updated
his name or not. If not, then show the employee
ID with their hashtag. Let's go see. This is my employee ID. And since right now
my name is not there, so we will be shown employee ID. This is done now to
format the data and all. I will use a package. So simply idea. Bob, add IN D. Intel package. I will be using this package
for date formatting. Will go to the pub spec
dot YAML and check. Yes, we have the package. Now. I want to show the
latest date here. So go check-in, check-out. Okay. Here. In that text, we have
to write the code. Date format, okay? Then yeah, right, format, which I want is
small VD capital M, and then small y 0
times so many times. That automate the time
that now like this. And similarly copy this
line and paste it here. And here. The format will be in the hours, minutes, seconds,
like this, okay? But obviously the seconds
will keep changing. So that is why we will wrap
this inside a stream builder. And here, stream will
be Stream dot periodic, const, duration, seconds, one every
second, just refresh it. So the seconds that is
the value keeps updating. Make it const, okay. Make it constant. Let's check it out. And let's see. I don't know. Stream dot, periodic snapshot. Let's say anything
again and sign. Since I have also
use another package. Let's check code,
unauthorized hint. This mattered. It shouldn't be, I
shouldn't get this error. Jwt expired, unauthorized
k. Let's see. I have the obviously it is working earlier that was there right now,
that it is here. I'm finding it funny. Go to this splash screen
and sign out. Now. Let's see what is dated. Okay. Expired token is expired. Let's see. I don't think so. I
have made any mistake. Let's check in. Check and see. Okay, and now
everything is fine. I don't know what was
the editor earlier, but I just sign out and sign in. And as you can see, the dime is there check-out? Check-in. We have everything. That's it. That's it for this video. I guess we have done a lot here. During the next session.
17. Attendance Table and Service Class: Hi, welcome back. So as you can see, we have the dates and
userData working, but now we have to work on the market and dense
functionality. So for that, first of all, let's create a new table. Inside supervise and name it. You can name it attendance. Attendance, disabled,
row-level security for now, and enable real-time because we will show that
history later on. Now. The first column
will be employee ID, foreign key, one
key two, employees. And the idea here that is the RTD not done employee
ID of that customer, because that is
not a primary key. This is the primary key. Foreign keys can be unlabelled. Assigned to a primary key. Then give it a
date of text type. Then check in. It will read text type. Then check out. It will be dx, dy. Hello. Kay. So save all I'm
just checking that. Yeah, employee IDs,
their date is there. Yep. Save. It is adding. Okay, this is done. Now here. Go to models and let's
create a model for now, and then then the file
and then model dot, dot, Let's say class. And then smarter by null. String ID. Buying, being date. By now. Been deck
in final string. This can be now level. Check out fine until they die. Created at, okay. Let's create the constructor which will accept this
value is acquired. This dot id required, this dot date required. There's not check-in. But in the case of checkout, we won't use required is will this checkout and then required, this dot created it. Now let's get the three. And then then smarter
and smarter dot Rahm. Jason will send a map of Jane dynamic data. And it done. And
then in smarter. Now here, checkout as well. Data employee ID. Then. Similarly the column
name is Jack in. Copy and paste. Check out. And this will be created at
and this will be timestamped. So we have to parse
it date time that bars because supervisors is not giving us in a
datetime format. So we will just change
the format here. Now. To work with then stuff, Let's create a new
service for it. Go to Services created, create a file limit. Then service dot dot. Let's create this file. Attendance, surveys, extense,
change note if buyer. Then as you said, create a spa base class and supervise Isabel dos base
dot instance dot client. Then, and then model, make it an unlabeled
for the time being. Then I will get that today. They tear the date
due date bottom at and this time. Not now. Next, we have the Boolean. Boolean is there in that
service is copy and paste. And I remember we are not
using this Boolean value here. So if you want, you can just remove it later on. Now we have this new provider
go to main dot dot file. Now multi provider
mentioned this name, that is attendance service file. And also in the
constants dot dot file, create a new static const. Then they will, they will
do then dense like this. So yep, that's it. That's it for this video. In the next video
we will work on the functions to get that
and then status and market. And then Thank you.
18. Function to mark attendance: Hi, welcome back. In this session, we will complete the
Attendance screen and create all these
functionalities. So let's go and create a
function to get the status. The go-to attendance
surveys here. And now. Let's create the function future and
get to the attendance. First, we will check
whether employee has tagged in part today or not. If yes, then we will store that data inside our
attendance smarter. That is, which is non-liberal. Let's light by another list. Result is it will do. So Bobby's dot from which
they were constants dot, then stable, dot,
select, dot equal. So we have to check
the employee ID. Employee ID is equal to value. Supervise dot dot,
current user ID. Like this. Okay? Then we will check if result is not empty, that is at least we have
some attendance data. Then attendance model is equal to attendance model from Jason. Result dot first. And then in the
end we will notify listeners since data for
that particular date. And also, I forgot. Here, we have to check that data as well because
get to date and end. Date will be equal to today. That this is important
obviously because there will be lot of
attendance in that column, but that particular date and that particular employee
will be only one. That is why I have
used result at first. This is the punch and to
get today attendance, that is I will just
show you as well, which they time talking about. This one today status. Okay. Then now the most
important function, punching to mark attendance. So let's create that as well. Let's write a future mark. Attendance sink. We require the bell contexts. Now here first we
will check whether employee has checked in
for that day or not. If not, then we will insert
a new data for that day. And if yes, then we will
update that data with that checkout time only because the user has already checked in. So let's write if attendance model checking
is equal to null, like this, then we
will add a weight. So Bobby's dot from constants, dot attendance table dot insert. Okay? Now obviously we are
inserting the data. Here. Employee ID
will be super ways. Od dot current user ID. Then they will be due date. Then check check-in will be date format,
hours and minutes. Dot parliament,
datetime dot now. Okay? So this is executed if the
user has not checked in, and suppose user has checked in, then we'll right away. Supervise the constants
that attendance table. Dot update, okay? We will update the value, but where that is dot equal, employee ID is equal to supervise that art. And here, obviously we don't want Alice only that is
we have to read else. If else-if attendance model
checkout is equal to null, that is, checking is there, but checkout is not art. Dot current user ID. And again, we'll check dot equals for that
particular date only. So you have to make sure that we are updating that date only. Okay, This is very important. Now go to the update
section that is here. Here we will only
update that checkout. Check out like this. And similarly copy this
line and paste it here. Okay? And now we have
the if, else-if, and then finally S that is
check-in is also not null. Checkout is also not null. Then we will show a utils
dot show snack bar. And message will be, you have already checked
out today. Okay. Then at the very end, we will call the get
today attendance. That is so that it will
get the latest data and update the UI because we have the
notify listeners here. So it will update
the latest data. With this attendance model, C, As you can see, we're updating that and then some model here. Okay? I know there is lot of code, but it is very straightforward. If you have any kind
of application, then you know that we
are just creating, updating, deleting data set. Now we have the function ready. Now it's time we make
changes in the UI. So go to Attendance
screen dot dot. Now, the first thing
we will do is in the init state called get to it and then put of wider context. We have to write
attendance service, dot, get to date
and dense in here. Listen will be false. Since I just want to get
that done thence initially. Then what I want is here, I relate by null. Then then service provider
dot off contexts, same thing of contexts. And now we have that and
then service provider here. I'm not calling this
function here because since this will be called
multiple times for that, for no reason, this attendance
will also be called. That is why I've only call it in the init state
for the first time. Then let's go to this children check-in. Okay. Now here, this check-in text, we have to change and just
make these things const, because these things
will be const. And Li, this texts will change. So this will be
attendance surveys, attendance model, checking. If it is null, then write the MD time or else
write that check in time. So this simply in
place output, this. If it is null, then output this. Okay. Similarly, copy this code. Go to the checkout text here, it will be Checkout, right that time here. If it is null, then simply use the
placeholder and make it const. There's things will
also be const. I know there are a
lot of const. Okay? So we have done now I'm just checking that everything is completed and not left anything. Okay? Now we have to execute the market
then dense on the slide. That is when they use this
slide to check-in, check-out. So here it returns
slide, Yeah, this one. First of all, we have to
conditionally output that texts. So we will seem again, attendance surveys. Attendance model. If check-in is equal
to null, then right? Slide to check-in. Here, right slide to check-in
or is slightly checkout. That's it. Then we have
the textile onsubmit, make it a sink and directly call attendance surveys dot
market than dense context. Then after this is completed, we will set that
key so that user can again use the slider. We have done all the things. It's time, we save and
test our application. Let's see if there
is any error or not. Oh, okay. I will go here in the attendance
and we'll just refresh. And let's see. There
is no data here. Now. If I check in, see see that check-in time. Is there 18, 39. Obviously, this time
is in the emulator. So that is why you
might be thinking, okay, here the
time is different, here the time is different, but at least the time of the
mobile device is checked in. So let's go and check. See. We have created at employee ID debt check-in,
check-out is null. So that means check-in is working perfectly and
we'll just wait for, for t. That is, so that I will check out and let you know that it
is working or not. Okay for tastes there. Let's check out. The checkout is also there done. It is working. Now if I go and see we have the checkout value updated
in this table only. Now. Suppose the user
tries to check out again. Then here will be shown, you have already
checked out today. That means you have to
come again tomorrow. Finally, Attendance screen
is working perfectly. All the functionality is flawlessly working and there
is no error in the code. In the next video, we will work on the
attendance history so that the user can see his bus attendance and check-in and check-out
time. Thank you.
19. Function to get attendance history: Hi. Welcome back. Now it's time. We work on attendance history. That is our calendar screen. For that. First of all, we have to add a new package. So open up a terminal and I add mine ear so that the user has can
change or select the year and month for which he wants to
get the attendance. That's it. If I go to Pub spec
dot YAML file, you can see here I have the
simple month here, bigger. Okay? Now next we will write def function to get the
attendance history. So go to it and then
service dot dot here. At the very top. I will create a variable
which will hold a mountain of searched data. So here, I'm just
thinking where to write. Let's write it here. Strain. Attendance is three. Month is equal to date format apical m, M, m, then small y, y, y, y dot format. The time. Now k. Then I will get there. I will let it get there, get attendance, History Month. And I will send a value this. And then I will have a set their attendance History. Month. We will then value here. We will like attendance month is equal to value and
notify listeners. So simply we are just
This is the month which heavily check
attendance history. So at the very beginning, the month will be
dead meant only. And then if you want,
you can change it. That is why I'm using this so that when it goes to
the Attendance screen, at least for that month, he will get the data already. Now, we will create
a function to return a future with checks that date column for the
search Montagnier. So let's go. Right. Future list of
attendance smartly. Get attendance, history. A sink. And Diane, okay. First, let's say the query
by analyst data is equal to await Superbus, dark
brown constants. Then then stable. Dot select dot equal column, employee ID, equal to supervise that art,
current user ID. And then we will do something like dot text search because
we have the date in string. So here also we are saving
the data in strings, so we will just compare. That is, the query is double-quotes then
inside its single codes and attendance History Month. Like this. And config will be English. English, like this. Order created at
ascending to false. So as you can see,
we have finalists. Data is equal to
average Superbus that from constant start
at an unstable Dot, select that equal employee ID, which should be equal to
supervise art user ID. Then dot text search. We will check the date
column and get all the rows, which is equal to that month. So we're sending this
attendance History Month. And then order should be
in the descending order. After this, we will
return data dot map. We will map the data. We will get attendance. It will be attendance
model dot Jason. We will send each attendance. And finally, we will convert this data in a
string, in a list. So this will become a
list of attendance model. So this is the
function. That's it. For this video. We will work on the UI portion in the
upcoming videos. Thank you.
20. Work on User Interface: Hi, welcome back. So now let's start working
on that calendar screen. Here we will show that
attendance history of the employee for a
particular month and year. So the first thing we will do is get the provider attendance. Surveys is equal to know
Vida dot of context. And I wrote, I should
cut and paste it inside the bill and attendance service. Okay. We have the
provider. Yeah. They will return column Harlem than children. Container. The container give
the alignment to alignment. Center left. Then margin, const, add in sets that only left-wing de dop 60. Bottom. Then, then child
will be const text. My attendance. Style, textile, give duff font size 25. Okay. Then below this container, row, domain X is alignment. Alignment dots space evenly. Here. We will show that
current month as well as a button to select a month. So let's write that children
plus texts will be. Then then surveys. Attendance, History, Month style will be const. Decks, died. Well in size 25. Then we will have
an outline button. Next will be week, month. Make it const. Okay. We have this become month. In the on-premise,
make it a sink. Then write Pi another. Select. The ID is equal
to simple month here, because this is the
package dot show Monday. Because dialogue here, we have this and we have to write disable future
is equal to true. That means this will
disable future years. Obviously the user
cannot go into future years and get
his attendance history. Then we will write string big month. That is, we have to format
this date in our own format, which is being used everywhere. So we will just say capital M four times
small vi four times. This will help us to compare
the data that is there. We have texts or channel. That is why we are
formulating selected date. Let's see. Make it await this simple mountain. And then simply change
that tenant surveys. Attendance, service
month is picked month. Now, if you go, that is attendance
surveys, History Month. This is a setter. See? So when we set the value, it will change the
value of this. And then notify
the listener that will rebuild the screen again. That is why we will get the
latest month in the text. So if I refresh it, if I refresh it and go say we have a various
why is this zero here? Ms. thinking? I don't know what's
there in your phone. I hope there is no adder. Have done everything correctly. And then dance history, m, M, m. And I think we I
have given this extra line. That is why that is
the only reason. It's a very silly
mistake that we have to make sure that these things
are being connected. So now, if I restart, and I hope it is character, if I go see a braille, 2023, if I pick them and to March, it will be March. Okay. That means it
is working till here. Now let's create the future
builder to get the data calling the get dependence
History function. Let's below this. We will write the
outset that row obviously upset this row. It is within the column we
have to write x bonding. Then you chart builder. Future will be, then then surveys that get
attendance history. Here it will bill contexts, context as seeing
snapshots, snapshot. Now we will add if snapshot that has they
didn't do something. As return, const. Linear progress indicator. Background, color,
colors dot white. And color wheel, colors,
gray, like this. And here in if
snapshot has data, then here again we
will check snapshot that data dot length
greater than zero. That is, if there is
any history or not. If not, then we will return const center child text. And here in the texts we will
write no data available. Make style of text style, font size 25. That's it. Now, what we will do is if snapshot dot data dot
length is greater than zero, then we will output
some kind of widget, which we will do
in the next video. Thank you.
21. Show the history data: Hi, Let's continue working
in the Calendar screen. Now, here, if snapshot that data dot
length is greater than zero, then we will return a list
view dot Builder widget. Here. Item count will be snapshot
dot data, dot length. Item. Below will be. Here. It will have contexts
and an index. Then we will get the idea and then smarter
since we know that daddy dies coming into typeof
attendance model. So then, then, then, then data is a good snapshot. Data. Index k. Now return container. Margin, gone. Edge insets. Not only give it 12, left, give it 20, right, give it 20. Bottom. Give it ten. Then height. 150. Then declaration. Const, box decoration, color, colors dot white,
colors dot white. Then box shadow will have box shadow color colors, black. When this six blurred
ideas then Offset two to k. Obviously right? Now. Just wait. We have the box shadow. Then after this, this
outside the box decoration, not Saudi, after the box. That though, right. Border-radius, border-radius dot radius,
that circular 20. Now give that child
to the container. And the container give it a row. Main exists alignment matrixes, alignment dot center class
will be as centered as well. Then we will have that children. So K, as you can
see here, children. Then now let's work
on that children. First children will be expanded. Container margin, const,
adding sets. On the end. Let's see what
value we will give. Will check the regulator
on const, box decoration. Color, colors, the red accent, border-radius, border-radius dot,
radius, dots circular 20. Okay. Then give this container
a chiral center. Now, we will meet that date, date format inside here, right? Capital E. Then change
that line to this. We will have the data,
the Sunday, Monday, and the date. Format. Attendance date dot
created that because this will be same as
well as the date. So it will be much more
easier to change it. Then give it some style. Const. Textile. On size will be a thin
color. Dot white. Font weight, font-weight, bold. Okay. We have this and
after this expanded, right, Another expanded region. We have a column matrix is alignment main
extracellular my data center, cross axis alignment
cross x is element that center than children. In that children
const text check-in. Now we will show that
check-in and check-out time. Style gave it some text style. Font, size, Duan
De, color, black. Then gone, just give, give it a size box, weight. The child divide this. This is the same as the I
didn't then screen text. Then state dot, dot, check-in. Stein, const, textile,
font size, give it 25. Okay. We have the column here. We have this expanded. And then similarly copy this Jacqueline expanding and paste. And we have main
axes, cross axis. Then text will be checkout. This is okay. We have the divider
then here, right? Checkout dot toString. And if it is null, then write that place
holder like this. And after this expanded, just give it a size box
that is inside that row. Remember, outside this expanded, give me their size box. Now, run the app. And right does still
occur if it is showing in my system
authorization and all. It is because I am using an emulator because
I have tested the whole application in a real device and it
was working flawlessly. So I think that if you
try it on your device, you won't get this type of
unauthorized and the expired. And now let's go
to splash screen. Sign out the user. Now k i. Now these errors, you won't be getting this
error scenario lower is because the right now, this is a virtual device
and I believe suppose that time is also different
than R. So again, I will go and login. I have that check-in check-out. And if I go to the screen, see I have the data and if I go pick a month
and give it March, then no data available. If I go and pick a Braille, then we have the check-in
and check-out date. And if you go to the
calendar, I don't think so. You require there
was an empty sets. This one you don't require because I think the spacing and all
is looking good. This is that at the very end, we did the size box. So this is the, that is why
we have this space here. Because it is all taking equals space because of
the expanded version. But I believe this
is looking decent. So that's it. Our attendance history screen
is also working perfectly. So let's continue in
that future videos. Thank you.
22. Function to get Employee Location: Hi, welcome back. In this video, we will
implement a feature of getting the current
location of the user. So while we are checking
in our checkout, we will also store the user location so that
it will be easier for the employer to check whether the employee is in
the office or not. So we will just do the location. I won't be checking
the distance and all. But obviously with that data, you can check the distance from the office and the
user very easily. Now, to implement that feature, I will be using that
package known as location. Here. This is the package. So simply copy it and paste it in the pub
spec dot YAML file. With this location, we will get the latitude and longitude. So just stop it and
restart the app again. Because we have
installed a new package. Simply go and start debugging. And as I was saying, we will store the latitude
and longitude of the user. And later on, if you want, you can use the package name is geocoding to get
that street name, city, country, and other
details from that location coordinate provided by this
package. So it's up to you. The package name is Joe. Wait, I will just
show you as well. That time it is
happening to coding. I believe it was
something to coding. But you see this is
the name geo coding. Yep. You can use that on
your own if you want. Now, in that location, I will be using
this code and I'll see this code I will use. So now, let's create
a new service Class. Insights Services. Creative file. Location, service, dot dot, simply right
location service. This is not the provider.
And divide it up. I will import material. Then I will import location. That's it. Now, create an instance
of the location. Then, right? Location, data. Log data. Then create a function which will return a map
of string double, that is latitude and longitude. And it can be null, sometimes. Initialize and get location. We will do board thing here. Site, contexts, contexts
to show the snack bar. Now the code will
be like Booleans. Surveys enable permission,
status. Permission. Granted. The first check whether location is enabled or not. In that device service and it is equal to
await location. Services enabled. If service not enabled, then we relate service
enable is equal to 08. Location dot request service. Then if service enabled, again phrase, then we were
like utils dot show snack bar. Please. Enable location,
service like this. And we will return null here. The other code
won't be executed. So this will be, this will be if service
is not enabled them. Okay? Then we'll check. If service is enabled. Then ask permission for
location from user. That means the user will get a pop-up that allow this
app to access location. So now we have permission
granted is equal to await location that
has permission. Similarly, we write if permission granted is equal to permission status dot denied. Then again add permission
that is equal to await location,
request permission. And again, if permission granted not equal
to permissions, they desk got granted. Then utils dot show snack bar. Please allow location, excess, return null from here. And if this is not the
case, everything is okay. After permission is granted, then return the coordinates. Simply write log
data is equal to await location that getLocation. And return it from here. A map of data. Let the dude is equal to log data dot latitude element. Here. This double can be null as well. Similarly, longitude is
equal to log data dot edu. So you might be thinking, what is this code? So if you go to the
official documentation, you will get the
exact code here. So you can just read or
copy or whatever you want. It's up to you. We're
not listening to background changes and
all that is why we are not doing any kind of settings. That is permission and all
foreground-background access. This kind of stuff.
23. Store location while check in: Okay, Now, since we will store this data in
that and then stable, we have to make some changes. So go to attendance employee. And in that attendance, edit the table and add column. Check in location, which will be in the map format,
that is Jason. And similarly like
check out location. This will be in the
JSON format as well. Just save it. Now, we have to make changes in the market
and then its function. So here in Denmark, attendance function
allow attendance only if that location
permission is granted. So here, first off,
map, nullable, get location is equal
to await location, service, initialize
and getLocation. Okay? Then I will write
if getLocation not equal to null,
then only execute. These are codes from here, copy and paste here. Okay? And here obviously we have
to save that location. So in the insert, we will check in location
with a big getLocation. And similarly while
checking out, it will read, checkout
location will be getLocation. Other things will be same. We are, remember
we're simply saving that location. Nothing else. We won't be using that location, but at least you know
how to get the location. Last thing we have to do is make changes in
their attendance model. Right? Final, map. Check in location. By now. Map check out location. Here. It will be this
dot check-in location, this dot checkout location, so it wouldn't be required. Remember here as well. We will write check-in
location will be data. Check in location. Checkout location data will
be check out location. So that's it. I will remove this data, attendance data because I want that check-in location
to be stored as well. Let's test the application. See check-in, check-out
is not there. So if I slide, it will ask the device location, I will accept it. Let's see. I hope there
is no adder because I know that if physical
device there is no error, but I am not sure
about this emulator. Let's see. There is no error is when. So here in attendance, screen, the market and lens. But what if location is okay? Deals not show snack bar. Not able to get
the yard location. What color will be colored red? Because obviously, God is and get to it in so
that the state is updated. But let's see what happened. If we check. Okay, as you can see here, it is not working. What I will do is I will show you this than running
in a real device. So now I have connected
my real device, and let's check whether that
location is working or not. So if i those slight
to check in, yep. I will be asking my
location and I gave it. And see. We have that check-in and that location is toward
successfully, I believe. So. Here we have that
check-in location. So as you can see, it is working perfectly
in a real device. Earlier, the only issue was that it was an Android emulator. That is the only reason or
else it is working fine. If I click on Checkout, then again, we have that checkout
location and time updated. So that's it for the
location and that history. These two pages are
working perfectly. In the next video, we will work on that
profile screen. Thank you.
24. Function to get all departments: Hi, welcome back. So now we will start working on that profile screen
that is getting all the departments and
updating the username. So for that, let's first create a new
model for department. Right? Department dot, dot, department
model, dot, dot, dot. This is a new model class. The part meant model. Final int. We will have the ID, that is department id
and binary string. We have already inserted few departments in
their database. Department model required, this dot id required
this dot title, then create a factory. Depart when a model from Jason, he was sending map
string dynamic data. Then they turn. Department model. Id will be data, id, and title will be data, and key will be title, since it's in a map format. Okay, we have the model ready. Now. Let's go to DV services. So since we will
allow user to update his name and department
in their profile screen. So let's create Panchen to get all departments in
that DV services. So here, That's right. You cheered. Wide. Get departments. Async. Now, we will first create
some state variables. First we will list
of department. Model. Departments is
the empty list for now. And we will have an integer
employee department, that is what is the current
employee department. This will also get changed if the user
select something else. So you will understand in a way. Now, in that get user data, what we can do is we can add if employee department
is equal to null, then then give it the employee. If it is null, then right, employee department is equal to user model dot user model
department is doing nothing. So what I did was, you have to understand this. That is, since this fun Chen can be called multiple times, that is, whenever we
call it notify listeners in attendance,
attendance screen. This function will call it since it has future will there. So then it will reset
the Department value, the part when value. That is why we are
using condition that is assigned a value only
if a department is empty. That is for the first time. I hope you have understood this. To assign on Lee and the time. That's it. Now in the gut all departments. Let's write a function list. Result is a weight. Superbus, prom, constant start department
table this time, dot select, we will select
all the departments. Then we will add all
departments is equal to result. Dot map. Here we will have
department. Then right? Department. Here we have to write department model from JSON and we will
send the department. Finally make everything to list and then notify the listeners to update
the value. That's it. Because here we are using the
listener will go in the UI. We will connect the
UI to this variable. It is we will listen to this
variable data. That is why. So that's it. We have created a
function to get all the departments in
the upcoming videos. We will create function to
update profile as well. In June.
25. Function to update profile data: Hi, welcome back. In this video we will write
def function to update the profile data
into DB service, right? Future. Update profile. We will require the
name Bill context. And we will simply await. This should be a sink away. It's super ways that
Rahm, constant start, employee table dot update name. We will update with their name. And department. We will update with the
employee department value, which is next state variable. It is here. Since
the very beginning. We will initialize it
with the previous value. And here we have to use the dot equals because we have
to change on live where ID is equal to supervise that ahd dot current user ID. After it is done, we will utilize dodge snack bar. Relate profile,
updated successfully. And we will give color
to colors dark green. And we will notify
the listeners. So that name in the
attendance table that is welcome ID or welcome
name will get updated automatically if we
use notify listeners here. Let's go to the profile screen. Here. We have to start working in it. First, let's create
some variables. Bursting with text
editing controller. Name controller is equal to
text editing controller. And then int selected
value is equal to zero. Let's see what we will do. Will this be required or not? We will check this later on. In the contexts
that isn't the bill will first create the
DB service provider, the service provider context. Context. And then we require DB service. After that, we will
call DV surveys. All department. If it is empty that is
not been initialized, then call the DV surveys, get all departments
are doing nothing. This code means call the get
all department only once. Then same, we will name
controller the text. If it is empty, then use named controller the texts value
to be dv service, user model, dot name. And if that is also
empty, make it empty. That is empty string. Which means is, if that page is loaded
for the first time, then go and insert the name controller texts inside the name controller
to be the same as the user model dot name. And suppose di user has
not updated his name, then just use the that is
empty string. Like this. We are using these conditions
using below conditions. Because belt can be called multiple times when
using notify listeners. That is the only reason. Now, let's work on the
body. In the body. We will check if the service
user model is equal to null. Then show a progress indicator. Because obviously if you
use a model is not there, then how we can show the data. Now start with the
padding rigid const, and instead start our Duan De. Then child will be a single
child ScrollView column. Then main exists element, that is main exits cell
in Mendota, center. Cross axis alignment,
cross axis alignment. That's centered. And then we have
that children 0, k. So let's continue from here. In the next video. In the next video we
will have the TextField and an option to
select the department, as well as a button to
update the user details. Thank you.
26. Dropdown menu to select department: Hi, Let's continue working
in that profile screen. So here in that column
we have that children. And within that children, let's start with
creating a container. Container, give it a margin
of const and inserts on Lee. At height hundred hundred. Decoration, box declaration. Border radius, border radius. Dots are cooler. 20 color colors dot
the red accent. Like this. In that child. Simply write grants. And third child, we
will give it an icon. So this, this is
just for the Use a look that this person did add. That is the look of the page. If you want, you can implement
image upload and on. Here. This is the and below
this container size box, box of height 15. Then text employee ID is equal to, we will call DB service. The surveys that UserModel,
not Employee ID. We will show him the employee
ID which we created. Then below this is
sized box of AI today. And then have it TextField x will controller,
name controller. The collision const,
input declaration, label, text, full name, full name. Give border, outline
input border. Now save everything. Let's see how it looks. See we have the employee ID. It is looking descent. We have the TextField
here for the full name. Now, here we will create a drop-down menu to allow the employee to
select his department. Now, below that text field, give a size box of height 15, and write dv surveys. Not all departments
that is empty. Then write const, linear progress indicator
or else Harris size box. Since I know that it won't
be empty because I have already inserted the
data in the database. That is why I will show a
linear progress indicator. Now in the size box. Give it a height of double-dot infinity that
is older size available. Then child will be dropped down. Form field. Okay? Here first thing
we will add declaration, Const, input declaration,
border, outline input border. Then value will be dv service
employee, department. If it is null, then use DB service.
Departments. First dot id value, that is, if the
user selects sales, then what is the ID? That is suppose zero, that
is the value which we want, not the texts, that is
a sales operations. I don't want the text, I
want the ID of that row. Then we have to write items. Items will be dv surveys, all departments dot map. Within the map we will have
the department model item. Now within this function will return drop down menu item like this. K. Now this code is getting, I know it is very difficult. But here you have to make it to list so that the error goes. And Within the value
and child is dropped, done. Item has value. It will be item.name, ID. But what should we shown? We will use a text field
to show item, dot, title. And style will be const. Text style. Font size 20, 0, k. Here it's a return statement. Now the final thing
which is required is we have the k within them. Dot dot button
field is onchange. So onchange gives us
the selected value. Here. If they use it, changes the value, then
we will write dv surveys. Employee department,
change it to the selected value. That's it. Now. See, we have sales,
marketing, everything. If you want, you can give some padding and
all it's up to you. Below this size box. Finally, we will have some
spacing size box height for D. And then again get
this size box. Here we will create the button. Size works with 250. Child. Elevated button. On press is there. And child will be const. Next. Update, profile style. Textile. One says when D N
in the on-premise, we will simply write dv Service Update Profile
contexts is there. And here named controller
dot text trim. That's it. So now everything is done. Remember, we are not sending the department id because
if the user changes it, then automatically here, the employee department
will be changed. And also, we don't require
this selected value variable. Now, if I go to the
employees table, we can see that department
and name is empty. Let's check. Department will be sorry, name will be a good while. And department Let's take it id, update, profile of the
dead successfully. C department to name is there. And if I go to the attendance, then we have welcomed
a whole Agawam. Earlier it was the employee ID, but since we are using the notify listeners,
it gets updated. So that means our update, update profile is also working perfectly all the sections. Now working. In the next video, we will work on the functionality
to sign out a user. Thank you.
27. Work on Signing out: Hi, welcome back. In this video, we will create a sign
out button here, which will allow the employee to sign out from this application. So it will be very simple
and straightforward. Go-to profile screen. Then here in that
column, let's see. Here we have column. We have children dove very fast. That is, before this icon image. Create the container margin, give it const. Edge insets that only
stopped when D alignment, alignment, dot dot bright. Then child will be
Next button icon. I can, whether it be const, I can I can log out. Log out. And label will be const, text. Sign out. Here. Let's change that. Top 200, 100, I will say when D, because we don't need
that much margin. Now, save it. Then if I go see, we have this sign
out button here, which is looking nice. I can see. Now simply, if you go to art surveys, we already have the
sign out button here. So Let's go to the profile
screen here in the on-premise. Simply write provider
of context here. And provider will
be odd. Surveys. We don't want it to
listen to the changes. We just wanted to call
this sign out Wanchun. Ok, save it. Okay, now let's check whether if we click on
the Sign Up button, whether we go out or not. See, as soon as I click
on the Sign Up button, it notifies the listener which call the splash screen here. See, this one was rebuilt and we were sent to
the login screen from here. That is why we don't
have to navigate, right, the navigation code, because it is automatically done here. And also right now, I don't have this, I don't want this code here. We directly mail sign out
from the application. If I restart, then also the login page will be
shown to the employee. So that's it for this video. Our app is completed, all the functionalities
are working. The only thing left is to work. If you go to the table. We have to work on
row-level security. So in the next videos, we will enable
row-level security and write policies
for the table.
28. Policies for Attendance Table: Hi, welcome back. So now the final
thing remaining is to enable row-level security
in our database. So row-level security is a security feature that
allows us to control access to rows in a database table based on a
user's identity or a role. In supervised, you can use
RLS to restrict which rows of data a user can see or modify based on
predefined rules. Until now, anyone with the public API key had
access to our database. That default behavior after enabling RLS to a
table Is that it denies all access
whether user is authenticated or not until
we mentioned our policies. If you go there, you can see after enabling
row-level security, all crud operations
will be denied. So for that we have to write
something known as policies. You can think of them as adding a where
clause to every query. Different table can have
different RLS policy. Maybe you want some table to
be producted, are maybe not. So let's get started. Enable RLS, go to
authentication, then policies. Here, as you can see, RLS is disabled in all tables. We will start with enabling
RLS in attendance table. And also, since I don't need
the application to run, I will just stop it. And let's focus
on Lee under RLS. So click here and it
will add a less than, are you sure you want to enable our row-level security
for this table? Attendance rate, confirm. So as you can see, RLS is enabled, but no
policies created yet. So let's create a new policy. And here you get two options. Get started quickly, and
create a policy from scratch. So for simplicity, you
will like to use the get started quickly
and after creating few queries later
on if you want, you can go for more,
more customization. Now, click on get
started quickly. So here you can see there are predefined templates that is unable to read
access to everyone. Then enable insert access for
authenticated users only. Then they will update access
for users based on their ID. So as you can see, that template is for
enable a bit axis. But when you use this template, you can even change what
access is required. That is, we will, we can use this template, but instead that
update we can write. Suppose select then enabled select Access for users
based on their email. So it's not
necessarily that if an only can be done
based on their email. And finally, it's given unable delete access for
users based on their ID. So you just read. Enable access for users
based on their ID, whether it's delayed, read, update, it's up to us. So let's get started. We will use the
unable insert access for authenticated users only. In this table that
is an attendance. We will allow insert anyone who, who has created an account. So use this template. Then here. As you can see, policy name is and it will insert for
authenticate users, allowed operation is insert. Target roles only authenticated,
which should be true. So we won't make any changes. Simply click on Review. You can see the query here. And remember, this query is what we can do on our own
inner customization section. If you know how to write them, postgres sequel query is
unknown, so it's good. Now click on Save Policy. So as you can see, we have successfully done our first policy which is inserting data into
attendance table. Now again, for second
polycyclic on new policy again. Then get started quickly. Now choose the template. Delete access for users
based on their user ID. First, glyphicons
use this template, but we will use the Delete template to
allow update excess. That is, employees can update
their own data on lee. Simply first change them. A policy name to enable update for users
based on user ID. Then instead of delete, click on Update, then you
have this extra field. Then what expression is needed? The condition will be if ahd dot ID is equal
to that employee ID, which is the column name. Here. User that uses underscore ID. There is no such
column in our table. That is I guess yeah. Employees table. Yeah. It was employees. I have myself forgot. It was attendance table here. Right. Employee ID. That is odd. Whoever is requesting
this excess, that is his ID, should be equal to the
employee ID field. Now simply copied and paste the same thing in this
recheck expression. These two will be saved. So now after that, click on Review and
click on Save policy. That is also then we
have successfully return the policy for update access
for attendance table. Then next, again, another policy for the
attendance. Click on get. Now, again, choose the delete access for users based
on their ID template. Click on use this template. Then here we will allow
a nibble select that is allowing read, a
reading this data. That is since we already
know we have a page where people will excess, that people will see their
own attendance history. So we will only allow users to access their
own history data. So click on Select. Then. Here it will be employee ID. That's it. So we have an inverse select
for users based on user ID. Then select the
employee ID here also, if you want, you can
add employee ID. It's up to you in the name. This is just a policy name. This one is the most important,
that is a column name. Click on Review,
then click on Save. So as you can see, we have successfully written policies for the
attendance stable. Since delete access is not given to the
employee in the app, we won't write the
policy for that, but I hope you have understood. Suppose you have that
delete functionality. Similarly, you can write the
policy for delete as well. It's nothing different
than all these policies. So that's it for the
attendance table. In the next video, we will write policies
for the departments. Thank you.
29. Policies for Departments table: Hi, Let's continue
working on our policies. In this video, we will work on the department's table here. First of all, enable the RLS. Then yes, we are confirmed. Then click on this, confirm. This is a religious enable. Then click on new policy
and get started quickly. Now, we know that the departments table
has no sensitive data. So we will use that template that is an invalid read
access to everyone here. It's up to you. If you want, you can use
it these read access for authenticated users only, but I will use this template. Click on, use this template. Here. We won't make any changes. Click on the View and
click on Save Policy. So we have the select policy
for departments table. And also we only need the
read access for this table since we are inserting department data directly from the supervisor dashboard
in this application. So if you go to
the table editor, if you go to the departments, we have inserted this
data directly from this, that is insert row, and that is why we don't
need policies. But suppose you
have an app which is different or you are allowing the company owner
to insert the departments, then you will have to
write the new policy. Then insert for
authenticating users only are read departments
for unleash. Admin are the owner
of the company. Like all these things you
can do, it's up to you. But since we have this
simple application, we don't need any
other policies. That's it for the
department table. In the next video, we will finally work on the
employees table, enqueue.
30. Policies for Employees Table: Hi, welcome back. In this video, we will work on them policies
for the employees table. So simply first enabled RLS. Then confirm. Then click on new policy. Click on get started. We will use that template. You will insert access for
authenticated users only. Since after creating an
account that is registering, we will insert a new
user data in this table. So we only want that inserting
for authenticated users. Click on, use them. We won't make any changes here. Click on Review, then
everything is okay. Click on Save policy. So insert is done. Then again, click on New Policy. Get started quickly. Now we have to create a
policy for the update excess. Choose the third template it is enable update access for users based on their
email template. So I hope you have
understood dead here. This will check, suppose from a user is
sending this request. Instead of checking the user ID, we will not check the art
dot email you can say. Then click on Use template. And now if you remember, we already have a
column named e-mail in our this table like
this employees table. So we don't have to
make any changes here. But if you have something like usury molar employee morale, then you have to write
the column name here. It is, employee slash
underscore email or whatever name of the column. Click on Review, and then
click on Save Policy. And finally, that third policy will be
for that excess cyclic here. And we will also use the
same template that is, enable access for users
based on their email. And also, if you want, you can use based
on their ideal. So but I will simply
based on their email. And click on Use is the policy
name to an invalid read. Users based on E-mail, allowed operations
would be select. This one is okay, that
is Emily's email review. And then click on Save Policy. So RLS is successfully
enabled in all the tables. And we have also
written that required. These policies. That is, whether insert is acquired
by the delete is required. It depends upon app to app. So obviously, the
user cannot delete anything since the
late policy is not their only does super
biased admin can go to directly through a
table and delete the stuff. This is also a good
thing that is, any delete request
will be cancelled. So that's it for the
row-level security part. I hope you have understood this. You might find it
very tricky since this concept is not there
in other Cloud services. Everyone has their
own thing, some, some security rules, some
has different things. So it depends upon the
Cloud service provider. But insofar as it is
very straightforward. In that next video, we will finally tests
that complete working off our application with the
row-level security enabled. Thank you.
31. Test the Complete Application: Hi, welcome to the final
video of our course. In this video, we will test
that complete application. And I'm using my physical
device here this time. And also we have enabled row-level security
in the last videos. So let's see if everything
is working perfectly or not. So let's go and login
with our credentials. 345. Click on Login. Okay. Everything
is okay till here. See I have logged
into my account. If I go I have this one, then then say straight that is. So that means that read access
is working perfectly here. Also read excesses there. That is, the employees table. Employee name is here. Now, if I try to do
slate to check in, okay, if they use a physical button, it is asking for the location
while using the app. And see, that means
it is working. We can insert the data. Rls is also working
perfectly fine. Okay? So profile is there. We have the full
name, we have the ID. And if I again check out, that checkout should also work. Yep. It also worked. So checkout is also there. If I click on
attendance history, I have today's attendance. And if I go and
change the name to just Raul and update it to
marketing and click on update. Yap, update, updated
successfully. It took some time, but I don't think so. It will happen again and again. If I just click on restart, then see we have a
whole now marketing. We have the department
of marketing. So our app is working perfectly. All the functionalities
are working. I will simply click on Sign out. Yep. I don't think so. This small lag is happening in your
application because I have test this
application again, in, again in properly
in my devices. This thing is just
happening here, but it is not an issue. So that's it for this course. I hope you have enjoyed
and learned a lot. Do check out my other
courses as well. That's it. I hope I will see
you in my other courses. Keep practicing.