Note Taking App .Net MAUI Blazor Hybrid and Blazor WASM - Single Codebase Complete Code & UI Sharing

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys I'm back with another video and in this video we are going to work on two different apps one for mobile dotted Maui 14 Blazer web assembly and the catch is we are going to use a shared code base for both of these apps so for dotnet Maui we are going to use dotted my blazer hybrid and for web we are going to use Blazer web assembly and almost all the code components everything is going to be shared so this is the app we are going to build in this video so first I'm going to show you the dotted Molly Blazer hybrid version so when we open the app for the first time it asks us to enter the name and when we enter our name okay then it navigates us to this main page which is which has this welcome away Prince it has this all notes section it has these two modes which we'll see when we add some notes then it has this Floating Action button for creating a new node and we have this plus button on the top right corner as well to create a new node and here also we have a Adder note button which we can click so all of these three buttons are going to open this new screen which is add a note page here we can add note title and then note description and if we save it without adding any details it will give us this validation error message the title field is required so because the title is required description is not required only the title is required so let me add some note let's say create a video tutorial for this app okay then we can save it by pressing the save button or we have this top right uh this check mark button we can save it from here as well so we created it and we can see the note is here now we have this title with dot dot dot uh because of the screen size constraint it cannot fit the complete title but if we tap on it it will open this title like this in a pop-up we can copy this and I'm showing this copied text so that we can see that something happened and we can share this by pressing this button and then we can share it using the device's native capability we can share it close and we did not add the description for this that's why we are seeing this description let's create a new node let's say second note with description and here a sample description will go here and save it and now we can see this in this first one now we don't see the set description button because we added the description and in here in the footer of this note card we can see the date time when this was created or modified and we have these three dots when we click on this it opens this new action uh pop-up so we can edit this note or we can delete this node from here and first let's add a description here so we can add a description by clicking on this now the title changed to edit node the node title it got populated and here we can add some description some random description description save it and fine now we have these two modes the layout mode basically this is grid layout and this is a list layout so we can choose these as well so when we are grid on grid layout it shows two column grid and when we create click on this list layout then it shows one note card in a row so you can see this complete details and same thing we can open the description like this click on it it opens the description now let's see these two actions when we edit a note it opens this edit node and it uh gets the title and description populated let's add some light updated and we can save it and the details are going to be updated and if you want to delete it we can delete it when we delete it says do you really want to delete if you press no nothing will happen as usual and if we press yes then this note is going to be deleted okay and all these this data is being persisted on the device that also we'll see okay so this is a demo on blazer.net Blazer hybrid let's see how this app looks on the browser using Blazer web assembly let's say it stop this select this one run okay I had these samples let me delete everything okay delete delete and let me clean it up first in here I I am persisting it in the uh local storage so let me clean everything up delete delete delete everything and let me restart this app okay so when we first open it the same way we had that name prompt on the dotted movie Blazer that tab same we have in browser version as well welcome please enter your name so we'll provide our name by Prince okay and now we can see the same similar uh UI welcome and add a note button and we have this add a note this Floating Action button here so we can create a node by clicking on this one so it opens a new page with this pop-up kind of structure in this and save if we save it it will complain about title field we can provide a title let's say first node on Blazer was inside without description if we save it it will be saved and it is going to redirect us back to the main page and there we can see the similar structure we have a description button because we did not add the description here let's create a new node a new note with description provided here goes the sample description and save it this time we can see the description right we have this date time when this was created or modified and if you click on this one it will open as the same pop-up with the node details and there is no title and description we can copy it from here and if you remember we had share option to natively share on the device so that was using a device's native share functionality but on browser we don't have that functionality that's why we have only copy here so the same alert we are using here to show that we have copied this thing we can paste it so let me show you we can paste it so this is the copied text we can close it then save we have delete and added functionality we can delete it if we delete it will ask for confirmation if we cancel nothing will happen and if we say okay then that node is going to be deleted and we can edit it using the add description button or this edit button so it will open up this edit screen the title is update node and then we have the same title was uh got populated then we can add some description here and then we can save it it will be updated okay so this is all and we can refresh it again because we are storing this data on the local storage so this data is going to be persisted so if you open it again we can see the same data fine so this is the app we are going to build from scratch to end in this video tutorial for both right okay with we are going to share almost all the code we will simply use the native functionalities for the part where we need to interact the native features for example fin browser we need to connect with the browsers local storage which does not exist in the dotted Maui side so in dotted Maui we are going to use devices storage feature but in browser we are going to use the local storage same goes with the alerts and confirm messages so in Blazer webassembly side browser side we have browsers alert and Confirmation uh pop-ups but in dotted Maui side we will use the dot and my device's native alert feature we'll use that alert for both confirmation and uh to display the alerts okay so enough talking let's get straight to the work here I'm creating a new project and the base project I'm going to have is dotted Maui Blazer app next and the name I am not sure what should be the names let me name it notes Maui Blazer was something like this I don't know if this name is gold or known but yeah let's go with this dot Net 7 and create and the project is here let me open the solution Explorer cool so we have one project here which has this dotted my blazer hybrid project basically now I'll add other uh projects to this solution first I'm going to have one Blazer web assembly app for our web assembly the browser version so for that let me copy this name and we'll call it this dot web notes my blazer version.web next it is going to be dot Net 7 configure for httpses authentication type none create cool we have this web web assembly project then there are going to be some models and other things which are going to be common between these two so for that we'll create one more project and that is going to be a class Library project this is for some common logic and common models for this let me name it same project name dot common next create cool after that we are going to have some razor components Blazer components basically which will be common in both of these apps so the dotted my blazer hybrid and the Blazer web assembly in these two projects so for that let me create one new project and this is going to be a Razer class library because we are going to use razor Pages Blazer pages so next and for this let's call it common dot components components notes my blazer1.components next dot Net 7 and spine we are good so we have these four projects let's add the relationship between all these projects so first Common is going to be used from all these three projects right because this common functionality common models we can use in uh main Dot and my blazer hybrid app Blazer web assembly and this common components so first let's go to dotted my ADD project reference we are going to add common and common component both because we are going to use both in this project add next go to the web assembly one so here also we'll do the same add reference and then we'll use common and common dot components in this one cool and then comes this common dot components in this we'll add a project reference and then we'll add the common in this so we are done with all these repair dependencies next thing uh inner dotted my blazer hybrid we are not going to use Mac Catalyst tizen and windows we are going to use only Android and iOS so for this let me clean this up so I'm going to delete Mac catalyst okay tizen I'm going to delete this as well so I'm cleaning up basically then Windows also I'm going to delete cool we have deleted these now let's go to the CS pros of this project and we can modify this as well we have Target Frameworks we are going to use Android and iOS we can remove this Mac catalyst then we can remove the next line which is for windows cool and same goes with the supported OS platform version so we'll use iOS we will remove matte Catalyst and tizen windows will remove all these fine so everything looks fine now let's build the solution solution and rape it we have this package downgrade error and this is coming from dot nodes my blazer version the main Dot and model project so we can add it explicitly so here what we'll do logging Dot abstractions right the name was a abstractions seven zero one seven zero one okay save and rebuild three will successful so everything looks fine till now and now we'll start working before that let's run the app first in both the platforms right now I'm running the dot and my blazer version app is loading we can see that loading initially and then hello world and the app is here this is the default template we can move around we can do all stuff right now stop it and now try the Blazer web assembly version foreign version basically the same version cool so project is in running State now we'll start coding directly okay so first we'll let's start from the Blazer hybrid side what we'll do first we'll simply clean all these things we don't need counter we don't need fetch data uh we might need index.tracer let's delete this counter delete this fetch data we don't need these two in shared we have main layout on Main layout for now let's get rid of everything we will simply have direct body nothing else so we can remove the nav menu and then we can remove survey prompt.racer as well cool so we have shared main layout which is the main layout and in Pages we have this index.reason we can remove this and hello world welcome to your new app let's call it.net movie Blazer hybrid okay let's change this to this one and let's see we should see only this thing first we'll see a small loading text in the laptop so it will be there because it is trying to load the Blazer project and when it is loaded then we'll see this hello world and welcome to daughter my blazer hybrid so we cleaned up everything cool after this let's do the same thing for Blazer web assembly version we'll clean that up as well same thing we'll do here in main layout we will remove everything we will have direct at the red body we'll remove this nav menu dot Razer we'll remove survey prompt.racer from Pages we'll remove counter will remove hash data and in index.racer we will remove this thing and welcome to your new app and here we'll save Laser Web assembly and let's run this this is loading our Blazer web assembly and then hello world welcome to your new app Blazer wall so we are good with this now we'll start working fine so we'll start working on Dr Mario Blazer hybrid side let me delete all open files close all all tabs now delete close all tabs let's jump directly to pages and index.tracer so if you remember when I showed you the app for the first time it was this we had after loading we had that uh nice prompt which was asking for our name and this time you saw it did not ask our name it did not show that prompt because we have that prompt already shared in somewhere in the device so for that we'll do this thing first we will show that prompt right so in index.raiser page we will check if we have that prompt if we have the data shared if not we will uh show that prompt and ask the user to provide his or her name so for that what we can do we can add a code block here and here we will override on initialized async and now we will check if the user has already provided name or no right so for that we need to have this name somewhere so for that we will use our devices Secure Storage or we can use preference because name is not uh that sensitive so we can use preference or physical storage both are fine let's use Secure Storage so we can use Secure Storage dot default Dot then we'll simply get async then the name of the key and let's say name of the key is username and we'll add a weight here okay what did I show okay we are missing using a sync now we'll check if not string dot is null or white space name not name it should be name fine we will check if the name we already have name then we'll continue to the app and if that's not the case we will ask user to provide his or her name right so for that what we are going to use we are going to use the current page Dot page apps dot current dot main page this is how we access the device features main page dot we have display action sheet alert and display prompt acing so we have display from pasting here we will ask user to provide his name so first is title title is going to be let's say welcome then we need to provide the message and in message we'll say please enter your name it returns a string so we can store this in the name now user might press cancel or maybe back button so in that case this will be a null if this is null then we cannot continue with our app so what we are going to do we will ask the user again so we'll display this prompt again and we'll repeat this uh for couple of time maybe two or three times we cannot uh irritate user so we will try three times and if user still did not provide that then we'll simply show an alert that you cannot continue with the app and then we'll simply exit okay so for that what we are going to do we are going to have constant let's say Max retry and we can have it some three we are going to have it three and then we'll do one thing which is going to be no not const we cannot have const because we are going to modify it so we'll say do this while so keep on repeating this line This showing the prompt until string dot is the null or white space name so keep on repeating until the name is null or MP or not core and the this Max will try so let me rename this Max retry so here we'll say minus minus Max Root right so we are decreasing pitch quantity this Maxwell price value and if this is greater than zero what does this mean so it will keep on repeating this line until these two conditions match so how these are going to work if we got first time here it will ask and if we provided the value it will simply come here this condition is going to be failed and then it will continue it will come out of the loop now next scenario if user uh did not provide user clicked on cancel in that case it will come to this while loop this case is going to be true and this time this makes you try it is 3 it will be 2 and 2 is greater than 0 this is also satisfied it will again open this thing so it will try now Max return is 2 then it will be 1 and then it will be 0 and when it is 0 at the third time then this condition will match but this condition will fail this Max will write greater than 0 this condition is going to fail and when this condition fails it will come out of this Loop so this is how this code is going to behave what is the issue here did I miss something this is from this else protected and this is here fine so this is how this is going to work after this we will simply check if we have name or we don't have the name so we'll check if string dot is in a lower white space name if we still don't have name then what we are going to do we will say await app dot current dot display app dot current dot main page Dot display alert and here we will say let's say error is the title and in message we'll say your name is required to continue on they knew with the app cool and after this we will simply return find what is the issue here display alert okay add button is okay okay we'll return and if that's not the case we have username here so let's Okay continue with the app right we have username here so we can continue that continue with that app so instead of doing this if and else because after this the code is going to be same and with this continue to the app as well so let's do the opposite instead of having this negation we'll change this condition and we will remove this else like this so we already have name we will simply continue with that right and if you don't have name we will try three times and if we got the name then we'll continue with the app right so here we are here now okay we need to have one more condition here that condition is in the else case or maybe we don't need this else we can have it here only we have username we are going to save it to the storage right so that it can get it next time correctly right so save it to the storage for this we will use the same Secure Storage dot default dot set async and then we are going to have the key which is this key the same key and then we will have the value and this time value is going to be list name which we got from the user and this is async so we need to await it cool now this username we are using it here we are using it here and we'll use these in uh web assembly as well so it's better to have this as constants the next thing is because these are going to be used in webassembly Project as well so we should have these in this common project so in the common we will create a new file new class here we'll say let's say app constants app constant fine let me make it public static and here we'll say public cons string const string and we'll say let's say is okay let's mean create a new class here first public static to group The constants for nothing else so we'll say storage Keys we can have it like this storage keys and here we can have public cons string username and we can have any name we want let me clean this up and we are good let's have this common uh namespace to in Imports and underscore imports.razer file so that we can use this directly in our razor components in this index page in this case so instead of having this username directly what we'll do we'll have app constants dot storage Keys dot username it makes sense now we'll do the same thing when we are setting the key cool we set this and now we can continue with the app and when we say continue with the app that means we will redirect user to some other page and that's some other page that is in order to move user to some other page in in Blazer we need to use navigation manager so we will inject that so we'll inject navigation manager we'll call it navigation manager only navigation manager fine and now we'll use this navigation manager dot navigate to and this navigate to will provide one URL and that URL in our case I use that homepage slash home cool so everything looks fine now the only thing is all this logic this should not be in this index.tracer page the reason is this is an internal Pace but what if somehow we directly land in some let's say intermediate page some internal page right it is not guaranteed that we'll use the slash only the default page in that case all this logic is going to be skipped and that does not make sense we will have in inconsistent State we will not have the user of State so the better place should be the main layout or instead of main layer we could have multiple layouts as well right maybe Blazer supports multiple layouts so for some of the pages we are using mail layout and let's say we created another layout which we are using for some other pages and if we directly land on those pages which do not have the main layout then it will be in consistent State then comes in that case we need to have that logic on Main layout and that other layout and again we don't want to duplicate the logic so the perfect place is going to be this main dot Tracer page so this is the main initial starting point of any Blazer app this main.tracer so we'll have this logic this index rotorizer logic is code block basically we'll cut it from here we'll go to main dot eraser and we'll add that logic here it will be loaded when the first time our Blazer app is loading uh either in dotted my blazer hybrid or Blazer was not Blazer server anywhere this is the first thing which is going to be loaded once so we will have this one issue initializing async only once and then we'll have this logic right now we need to inject this navigation manager here so let's cut it from here and let's have it navigation manager injected on this page fine save everything and we are good now the only thing is now we need to pass this name to all internal pages all right we have this index.traders first thing let's change this index.page content we are not going to have anything here or we can have simply uh loading state or something like that you can have it like this save we can say okay we'll we'll see later what we are going to do on this page for now let's have a empty span we are not doing anything we will do or let's say checking or state or something like this fine main dot razor we have this everything looks fine and let's run it we'll see how it is behaving remove we are on home by the way that was the previous app I showed you it is loading loading Blazer is loading checking out State this is index and then we have this welcome please enter your name this is coming from this main.tracer okay and see if we cancel it again we got it if we cancel it again we got it again if we cancel it again then we have this error your name is required to continue with the app and we have okay and in this case we should change this tracking what state we should have some error message so that will do but let's run it again this time will provide the name and when we provide the name it will freak out let me add the [Music] um break point here right now it is at this place this one so let me provide the name away okay we are here okay it was coming from here so we are here now we can check we have name as abhay it is going to save the state and we are going to continue with the navigation manager dot navigate to home which does not exist right now so it will say the default sorry there is nothing at this address and this is coming from the uh main.tracer where it is from here if the URL not found it shows this sorry there is nothing at this address cool stop it and let's run it again and this time we have name directly because we stored it we saved it in the device is Secure Storage loading checking out state it came here and this time we have name already and we'll continue so this time this is going to skip this and this navigation manager and we don't have that page right now cool so looks like this thing is working now we are good with this logic there is only one thing the same logic we need on our Blazer web assembly project site so let me know there Blazer vast web so we need the similar thing let me copy this and we'll paste it in our web and at same place assembly we have the same thing in app.rezer this is the starting point of our Blazer webassembly app so we'll add that code here right and this import using namespace this common you underscore Imports your Tracer we will do same thing for Blazer webassembly fine save and now everything looks fine there is only one problem but before that it cannot find navigation manager we can inject this in app.racer as well so let me do this inject navigation manager navigation manager fine the only thing is the Secure Storage now this does not uh exist in the Blazer web assembly because there is no security in the browser we have local storage and social storage we can use those and we can access those using JavaScript basically fine and then comes this display prompt and display alert so for alert and prompt also we don't have these these native things in the Blazer webassembly browser side we have the browsers prompt and alert so we need to access those and these will be accessed from the JavaScript side as well now if you see first we can modify these no what we can do we can inject we'll do a similar different approach but for now let me show something to you so we can inject I JS runtime and let's call it JS runtime only JS runtime fine and from JS runtime when we are fetching the name what we'll do we'll say JS runtime dot invoke async type of data we are looking that is string string then comes the method name the JavaScript function name so that we are going to have window dot local storage store what is the shoe window dot local storage window Dot what happened to my keyboard okay something is not right with my keyboard then we need to pass window.localstorage.get item we have this get item function on local storage and we next thing we need to provide the parameter name and that parameter name is going to be the T and the key we have that is this app constant storage key dot username okay something is still not right okay my keyboard and mouse these are freaking out fine so we have this name we got it from JS runtime window.localstorage.getitem let's do the similar thing when we are setting the item at this place so let's copy this complete thing will come here we'll say this this time we need to set the item so we'll use invoke void async method which does not return anything and instead of get item we will say set item which expects two values first one is key and the second actual value that is name now we can get rid of this thing next thing we need to show prompt and in the browser we can display the prompt let me use this thing first name a weight GS runtime invoke async and it will return string and actually in the label string and here we can say window Dot prompt this is the method which we can pass to the browser and then we can pass the math message and that message is going to be welcome please enter your name so how we cannot pass two parameters to this it expects only one parameter so instead what we'll do we will pass only one but we'll use next line character slash nine so this is going to break this in two lines welcome then please enter your name cool now for displaying the alert similar thing we will use this invoke yd async invoke wide async and this time the method name is going to be window dot alert and the value same it expects only one value but we need to pass two values so we will do the similar thing we'll use the new line character and then OK is not going to be there because we cannot have buttons here so errors are gone looks fine on pages index.tracer let's have the same thing which we have there so we'll have a span we'll say let's say checking our state cool let's run this now let's see what we got okay it is coming app is loading and we have this prompt welcome please enter your name we'll cancel it it will ask again win cancel it it will ask again we'll cancel it now we have that alert okay and we do not have anything now let's restart it this time we will provide the name this time we will provide our name we'll say OK and now it navigated to slash home which pays the that this page does not exist so we have this sorry there's nothing at this address and this time next time we feel open the app again this time it should directly navigate to slash home because right now we have name stored in the local storage we can check it it navigated to directly home and we can check it in the browser's console application local storage and we can see this username away so it got set okay so the same feature same thing is working but there is one thing that thing is we are duplicating the complete code right so we should not duplicate we should have it at some centralized place now we need to find out what that place is going to be now the problem is this JS runtime and all these things these uh can live inside Blazer webassembly only but the Secure Storage and app.current Dot main page this can live inside the Blazer dotted Maui side only so where should we put this and if we are going to put them in common then how we are going to get the correct implementation so we should have something which will provide that the the OS the platform is this then pass this and if the platform is browser then pass those yes in uh print time and all those so that this thing we are going to do next we have two projects for common uh things so we can put the common things in dot common and Dot common dot components so dot common dot components this is uh Razer class Library so it is going to have our Blazer razor components but in this case the thing we need to share that does not involve any HTML or any template thing this is purely code related thing right the direct C sharp code so we should have it in our common project right so in common will create a folder let's say we'll call it services okay and in this services this is not proper authentication but let's consider it as auth because we are getting the name so we'll name this as auth service so we'll save it we'll say auth service foreign let's say public class auth service and in this auth service not services or service rename service yes cool now in here we'll have a method public async task string in the label string will say get or or maybe authenticated username something like or let's say get username get user name and we are good now we need to have the um this logic in there so let me copy this note navigation manager accept navigation manager will have everything now comes the issue the same issue I mentioned that we have two different storage options for Maui we have physical storage for webassembly we have local storage same goes with this app.current.main page dot display prompt and alert for prompt and alert we have different implementations for Maui and for webassembly so how can we combine this the option we have we can have an interface which will give these methods the centralized methods and the implementation we will provide if we are getting this from Huawei we will provide an implementation of Maui and if we are calling that from Blazer webassembly we'll pass the Blazer webassembly implementation yeah sounds cool so let's create interfaces so we'll create or maybe let's have a new folder all together here so we'll create a new folder and we'll call it interfaces fine and here we'll create our interfaces new item code interface and the interfaces we are going to call so we have two things right first we have storage second we have these alerts so we'll create two interfaces first let's say I alert service Pi alert service changing to public and from alert now let's create second one also public interface I storage service so we have these two interfaces okay the methods we need in alert we need two methods first one is public async task and that is for prompt and we'll say uh prompt async right and in here we can pass message and title title fine or not public async my bad task string prompt AC the second one we are going to have alert so task it is not going to return anything we will say alert isync and here also will have the same parameter string message string title and this time title we can have the default and that is going to be alert and then the third optional parameter we are going to have button name basically because we have this functionality on Maui side so we are going to use this and we cannot have the button name that okay cancel button names on browser side but we are good because we have this functional term outside we can pass this so okay and we are good with this now let's go to storage service and in storage we are going to have two methods first one is to set the data so for that we can have task and we'll say save to storage or let's say save and in this we can have a p and value and then we can have another one which is going to be this task of string nullable string it can get written null we'll have get async and this time we will not have value we will have simple key right so save these remove everything clean and let's move this eye storage service to its separate file right now we need these two that's why we are using these two methods but we will keep on adding other methods as we need them on the way right cool is it visible it should be fine so now what we can do in this auth service let me remove this first instead of directly using these things we can inject these so what we'll do we'll have I alert service alert service and I storage service will have a storage service let me add the fields for these private read only fields storage service now we are going to use these things in these methods right so when we are getting the name instead of getting it from securestorage.default.getysync what we'll do we'll say the storage service dot get async then we'll pass the key when we are here when we are displaying prompt what we'll do we'll say alert service dot prompt async and from here we can have the same message and title okay we need to change this so title is going to be here and message first message and then title cool same thing display alert so here what we'll do we'll have our alertservice DOT alert async and here we need to provide message title and button so we'll have message title and button just we need to change these first message then comes title and then comes the button and we can return from here go to the issue string task is required okay because this is we are returning something from here we can say return now we have the username then we need to set it is to the storage so instead of using this we'll use storage service Dot save async and then we'll pass the p and value cool and after this we need to return to the name fine so everything is fine remove this not service we have this auth service now we can use this hot service from both the places right so let's do this we need this auth survey so first thing we need to add this to the dependency container so for that I am not using any interface for this but if you want you can but because this is going to be same this is not going to be changed or multiple uh implementations of this so I'm having it like this one day okay so you can inject it if you want you can add it add an interface but I'm not adding it so now we have two different projects so we need to add these to two different uh files basically we can have so we'll say Builder dot Services Dot add let's have it as Singleton or maybe Transit we need it on the first on the first page only transient and we need our service save and copy this this is in Blazer web assembly I'm sorry dotted my Blazer and same we will go to web project here we have program.cs and here before build.run async will add this save everything and we are good now the only problem is it will freak out because this auth service requires implementation of these two things alert service and I storage services so we need to provide body for these two services for that what we'll do we will create Services folder in a dotted mobile project so we will create a folder services and here we'll create two files one for alert service and one for storage service we will say alert stir with public plus alert service and we'll Implement I alert service interfacing my alert service cool we'll implement this interface like this so this is dotnet Maui and we know alert what we can do now let's see if we sync and we can use page dot current and again I'm doing thing app dot current dot main page dot for display we have display alert message title button name but message new title message I should have named it like that only but yeah no problem like this it should be awaited fine and the same thing the similar thing not same thing we'll do in prompt testing this time we return main page Dot prompt async display prompt async and this requires title message and then OK button so title message and okay button that means the same signature what is the issue okay button names so here we'll hard code it to ok cool so we are using this thing at both the places and the type of main page is page so let's do one thing let's creates a Constructor and let's have it private read only in a label page here no page only underscore page and we'll set it inside its Constructor so page equals app dot current dot main page then we'll use this underscore page underscore page we can remove this app we can have this current directly but I like explicit thing so if we can get to know that this is coming from app and here also we will say underscore page and we are good with our alertservicein.net Mall let's do the similar thing for storage service so public class storage service coin and here we'll Implement I storage service so let's implement this Implement interface fine and we are say when we are saying get async this time what we are actually doing it should be nullable right task still decision level this should be in the label that is sync fine and from here we will use a weight and we'll say Secure Storage dot get async like this and when we are saving we can use the same our weight Secure Storage dot set async the end value and we are good here also we are using Secure Storage for both the places so what we can do we can have this I'm using this approach so that if tomorrow we want to uh okay that we can use from here also we don't want to modify it but this is a best practice we should add dependency in here only we can inject these if we want or we are not injecting then we can use this approach that uh assign the values in the Constructor so that we can use it throughout the class cool so the Secure Storage we will use here private read-only High Secure Storage and we'll call it storage and here we'll provide storage equals Secure Storage dot default row I made a mistake here so underscore storage we'll use this underscore storage and here also values underscore storage fine so we are done with these two Services now let's inject let's register these services to our dependency container right now we are in Mobile project only so we will go to Maui and here we'll register these to Builder dot Services Dot add Singleton we are going to add first high alert service like this and we are going to set the alert service for this which will come from its services cool and then we will do the same thing for the my storage service my storage service and the implementation storage service cool so we are good with Maui project now we need to do the similar thing for our web assembly so for that also we are going to create a new folder in our Blazer webassembly and that is going to be you guessed it right services the same approach and here also we'll create plus which is alert service the same name service and let's copy the implementation from here so we'll copy both of these we'll change the values for sure but let's add this here we need JS runtime here for that let's inject this I JS runtime and underscore JS for runtime by JS runtime we are injecting it JS for runtime this will be provided by a framework only Blazer only underscore JS runtime equals list JS runtime and we are good with this now when we are saying alert async what we need we need underscore JS runtime dot invoke void async and in here we need the identifier that is the name of the function JavaScript function in this case which is window Dot alert and then comes the parameters to the function so in our case the parameters are first we will have title then we will have a new line then we'll have our message so we are good now let's copy this similar thing or not don't copy we will say return underscore Jrs runtime dot invo casing this time we'll use invocacync not invoke while async it will be in a label string and the type of the name of the method is going to be prompt prompt this is coming from JavaScript and then same title and message we can copy the same thing like this tool and we are returning something decisional label this should be in a label and this should be forwarded and when this is awaited it should be an async method so we are good with alert service now let's go to the Secure Storage the storage service instead of using this my secret storage what we'll use here okay the Storage storage we cannot have it like this so we need to inject the same IGS runtime so I'll copy it from here I'll do this and Constructor should be this rule yes runtime so we are going to use this JS runtime only so underscore JS runtime Dot saved invoke async because we are getting some data from the browser and the type of data is going to be an enable string and the name of function is going to be window dot local storage Dot get item and we can have one thing here we can say private read only read only in string weekend State Storage name underscore storage name or we can have it as a constant also but let's have it like this only here we'll say window dot local storage and then we can use this underscore storage name directly here so what we'll do so instead of this hard coded here we can use like this the benefit of this is uh if you want to change it to session storage tomorrow we will just have to replace this one line so everything else in this this class file is going to be same so we don't have to make changes at multiple places this is the benefit of using this approach right now let's use all best practices like this and like this fine then we can next thing we need to pass the parameter for this function and in this case the parameter is game now key sorry cool the similar thing we need to use when we are saving the data this time instead of invok async we will use invoke y dashing because we are not getting anything in return here we'll do the similar thing instead of get item we will use set item and then key and value like this and our storage services also done now we have all these two Services let's inject the let's register these services in our program.cs so we can copy these two lines and then we can add these lines here so we'll register these a Singleton the name space is going to be web dot services this one cool we are good the only thing is let's move these two separate files so move type to storage we have two alert Service and Storage service in services and similar thing we'll do in Maui and we are move type to storage Services cool next thing is we need to inject these things in our pages first let's do let me close all tabs first and when we are working with Maui let's go to main.razer and we need to have that logic here that auth servers here so for that let's inject that auth service or service and that all service we are going to get it from the name States this one this is coming from this name space so let me copy this name space and add it to imports.racer in both the project so in Maui at the rate using this and the same thing in webassembly fine now let's save everything main.razer now we can get the block service then we'll say odd service now we have access to this auth service so in on initialized async when we were patching the name what we'll do we will simply for now let's comment everything out let's have this navigation manager here only and what we'll do we'll say one name equals um avoid or service dot get user name fine now we'll check if we actually got username or we were not able to get the username so we'll check if string dot is null or white space that means user did not provide uh the what we call it the name he did not provided anything in the prompt and we tried three times when we did not get anything in that case we are going to return from here string dot is now yeah and if that's not the case we will redirect user to home so let's try to run them away app we have made so many changes let's try if everything still works uh the same so we are in dotted Maui run it let's see app is loading now let me quickly add a breakpoint I don't know if it is going to hit or no yes cool let's add a breakpoint at next place as well continue oh we already have the name set in local insecure storage so this functionality is working we can continue and we'll say sorry there is nothing at this address that means the happy flow that is working so this thing we got the data in our storage so the flow is working interface and implementation is working now let's to check if this is actually working let's uninstall the app so the name is notes Maui Blazer nodes where is nodes this one let me install the app and install okay and let's run it this time it should display that prompt and we have this prompt we can cancel it it will come again we can cancel it it will come again and let me cancel it again so we have that error that means alert and prompt and storage all three services are working fine we are here and now we can return and nothing will happen let's stop it and run it again this time we will provide the name so it will navigate to slash home where of course there is nothing at that address continue we have this will provide the name okay we have this name this time continue and it got navigated so everything looks fine everything is working as before this time with the code at centralized place and that's common right so we can get rid of this complete thing let me delete thing so we'll do a lot of this kind of stuff first we'll Implement something then I'll show you the better way to do that so we'll do a lot this thing in this complete video okay do uh please do let me in the comment if you are liking this video and if you are learning something new fine now let's go to our uh Blazer webassembly open app.razer same thing let's comment everything and now we can copy this thing directly right copy and let's paste it here the only thing is we need to inject the sort service we don't need IGS runtime this time we need just auth service and navigation manager fine let's try to run this so Blazer webassembly run let's see and it got redirected to home because we have the data let's do one thing go to application local storage and let's delete this username fine remove the slash home and let's run it should show The Prompt this time it showed the prompt welcome please enter username we'll cancel it cancel and cancel now we can see error your name is required that means prompt and alert both of these things are working let's run it this time we will provide the name and we'll provide our name our place and we'll say okay and now it got redirected to this one now if you open it again it will directly redirect to the slash home because we have the name inner local storage application and we can see the username of apprents and that means this thing also working and we can get rid of all this code cool fine so so far so good everything looking great good we need to pass this name to all other components all other Pages whatever page we have we need to have this name so there could be two different approaches so when we can have some centralized service basically a state it will have a class and we will inject that service here we'll set the name here and all other components and Pages can access that property from that particular State and we need to register that state as a single term so I already created a video related to this and you can find that on my channel it is uh sharing or passing data from daughter model to Blazer Blazer to Mouse so that is the similar approach but in this one we have the second approach that is cascading parameters so cascading parameters the way it works it is kind of provide an inject we will provide the value from here and it will be accessible throughout the app for all the child components in this case we are adding that cascading value here on this app.rezer so This value is going to be available throughout the app because each and every page is going to be rendered inside this router so we'll have access to this cascading value which we are setting here here we'll set two things first this name and we can have it hard coded name or we can have it Roma app constants right so in app constants let's have or maybe let's reuse this storage Keys username so where we can have app constants Dot uh storage Keys Dot what was the name username username [Music] fine and that will have a value and that value is going to be this name and we don't have this name outside of this phone any slide so let's create the variable here which we'll say let's say underscore name with default value as empty underscore name and we'll set this underscore name here like this like this and we are good oh it can be the label okay so we can have another approach as well and that is going to be we'll set this underscore name after this let's do this here and there is code name equals name and then we'll set this value to this underscore name fine now we can access this value throughout the uh app in all the pages so let's do the similar thing in our main dot tracer will have this name main.tracer like this after this we'll set underscore name equals name and then we'll wrap this in this cascading value like this like this so do let me know in the comment if you were aware of this cascading value cascading parameters if not I can plan a dedicated video for this and do let me know in the comment if you want a dedicated video for sharing data in Blazer apps cool next thing we need to have this slash home this route so now we can have this home page this will be kind of same for both Dot and Maui and Blazer web assembly so this page is going to be common so the best place for this is going to be this razor class library that dot common dot components project so here we will create a folder that is pages and in this pages I will add a new razor component and I'll call it home page right or we can have it home only but we are good the route for this is going to be the thing which we are setting right that is this phone okay so home page and we'll call it from the common components let's see if we can get to this project right so we have this project referenced from our Maui and Blazer webassembly first let's work with uh mark from Maui only we have reference to this and we need to add this page to Blazer this Norton Maui so the way we can add this is when we have this app assembly at this place the if we have routable components in this case this page this is a routable component routable components means which has this Android page attribute and we are navigating to this using some route in this case that is slash home so if we have routable components in some other assembly so the way we can add that on this router we need to tell the router that there could be some other assembly where you need to scan the routes so we have one attribute the parameter this additional assemblies we can have the additional assemblies which is of type I numerable assembly so we need to add the assemblies in this case we will simply add a new array and here we'll say type of the input of that is our home page and our home page exists in here which is in common components homepage so we need to access this eraser we need to add the namespace in the import sort result so after common we have components after that we have pages now we can access this home page yes we are able to access this after this we will have assembly because right now we already have we only have the single assembly so we'll do this and we are good we added this additional assemblies so whenever we are navigating to some page it will first check in this assembly main which is the same Dot and multi project and then it will also scan this assembly which is this common component assembly so it will check all these at the red page directives and it will get to know okay this is the slash ohm that means it need to render this page fine if we save it and everything looks fine let's try to run them away app now it should show us that home page from that components project it is loading and home page from common components this is fine let's stop it and do the similar thing for our Blazer web assembly the only thing is we need to do first we need to add the namespace in underscore imports.resent let's go here in dot web project webassembly we will add it here common components dot pages and then we'll add the additional assemblies the same way we added in the mouth project in Maui we added it in main.razen in webassembly we'll add it in app.tracer after on this router after app assembly we'll do this additional assemblies and now let's try to run webassembly project it should also open the same home page from common components let's see it is loading and we can see the home page from common components cool stop everything and we are good now next thing is let's access this cascading value this parameter this underscore name on that home page right so it will come from both the projects let's go to components home page like this here we'll add one H1 and we'll say welcome and we'll say username underscore username something like this we can have and now we need to access this username so the way we can access the cascading parameters will have a property here which is of going to be of type string and we can name it whatever we want in this case let's name it username and this should be a cascading parameter because we are going to access the value from cascading value cascading parameter user name and we'll tell which cascading parameter it is so this is going to be the name equals app constants dot storage Keys dot username this because if you remember on app.rezer and main.reaser we set this name so we are providing this name so this is here and next we will provide uh default value for this which is system.empty and now we can access this add direct username here cool so now this should work for both the platforms dotted Maui as well as this Blazer web assembling so let's run it first we are in webassemblies let's run it we should see welcome then the username okay web assembly is coming and welcome away Prince it got the name and let's try the same thing for DOT and Maui run it sorry dot net Maui loading and welcome so that means this cascading parameter cascading value is also working the value is getting set successfully and we are able to access this value and the this common component this is being used from both the platforms right cool so now when we are here we can start designing our app cool okay let's see what we need to build so we'll see here sample app which is this one okay first thing we need to have this background color which is throughout the app right this background color cool and this background color we need to set it throughout the app so we'll have it in the this common components 5 right here in this triple W root we'll create a new folder that is called CSS and ncss will add a new item which is going to be web SB net core web content style sheet so we can say common dot CSS go to Innovative name common.css we will have our color here so let me copy the colors so we have the colors here and we are adding these to root so it will be available throughout the app we have these three variants of this game color main light and lighter so this is the darker and these names are not very descriptive but let's have like this only main is the dark color this is light and this is lighter so these are three labels of the colors fine after this we will simply use the body tag and we'll say the background color background color of variable and the variable is called our main fine apart from this we will use the this font is not the default font so we will change the font we'll check the Maui project we have CSS we have app.css and we are setting this font open iconic and all this we don't need this we can get rid of this then HTML and body we can comment this out as well we are not going to use this font family we'll use our Point family from common.cs because we need the same font for both the versions so we'll use from here so HTML and body and font family this but we'll need our font so let's let me copy that font we are going to use Ubuntu font which you can download from Google fonts I have it downloaded let me add it so I have copied this fonts Ubuntu bold and Ubuntu regular in our triple W root folder in common components right so in here in for our HTML and body what we will do we'll set the font family or something is not right my mouse and keyboard are not working properly okay so the font will use Ubuntu and the place from where we'll get this we'll have SRC oh not like this we need to have this in font family so we'll have font face this is all CSS so we need to cut this add this here like SRC SRC is going to be relative to this URL which is dot slash we have fonts folder here not touch slash we have dot dot slash we have phones and then in here we have our Ubuntu regular.tf let's use this and then we'll say the format is true type ttf cool now we can use this in HTML and body like this point family and we'll use Ubuntu here and we should always have some fallback points so let's use the same which we were using before so that was this helvetica like this only we can have like this cool so we set the font family we have this body where we set this background color as Main font space now this common dot CSS we are not using this file right we need to have this common CSS for our page and in dot net Maui in triple W root folder we have index.html this is the main HTML page 4r complete app and here we can see the CSS app.css file which is specific to this project here we need to access that file the way it works let me copy this same app.css and first we'll have that common file and that we can get how the Blazer shared result class libraries work we can get those by dot slash underscore content slash then the uh assembly name so in this case assembly name is node smallblazer was not common dot components let me copy this and come here after slash content we'll add this and now we have access to the triple W root folder of this project in that we have CSS then common.css so slash CSS then we have common dot CSS common dot CSS so we have this common Styles first then we have app.css in which we can override some style which will be we can say the platform specific if we want to do this we can do like this cool let's save it and let's try to run it and let's see if we are getting this background color and different font app is loading and we can see the background color this darker color and we have this different mode I don't know if you can see it because of the color the color black is not perfectly visible on this color so but we can see something right so that means that styles are getting applied okay let's continue let's see the app the first we have this header section which is this name and then this plus so let's first design this thing it has this darker color some Shadow and these two things so let's first run it and then we'll see it so for me the hot reload in dotted Mario Blazer hybrid sometimes it works sometime it just does not work this time let's see if it is working or not um where is our home page home page homepage dot Razer file we are here let's start so we need that header for that let's start so first we'll have a div class first thing we need to have text White and we need to have that background color or we will use the same header for the next page the create save or edit note as well so let's have a common style for that header that never that we are going to have in common dot CSS right and what that style is going to be let's will call it let's say Maui nav bar in this we'll add this now first thing let's have a container where we will have the header name which is going to be this welcome and the username save it and can we see it yes it is working cool we have this thing after this we will have that plus so we are going to use nav link and all this long line let's cut it and add it to the import slot eraser so that we don't need to add it again and again in common components at the rate using add this and now we can directly use enabling component cool nav link href and that is going to be let's save that new component will create later and we'll add couple of classes here class this is going to be this class in this class fine first vtn BTN default text right foreign Plus so save it and let's see how it looks and oh there is some error reload okay if there is some error let's reload loading checking and now we can see these things right now let's add styling to these this Maui never CSS class so we'll uh add this and we'll see this side by side okay one thing which I'll do here it should not be in common because this is Maui specific so there is no point of adding it in common because we need this only Maui side not Blazer web assembly side right so four dot and Maui we have triple W root CSS and then app.css this class so here we'll add the styling for this first we'll set display Flags after that we'll use justify content it should be Center align items not Center align items as Center so this align items for vertical uh and then this justify content this is for horizontal so instead of this before that justify content it should be spaced between so that these are side by side left and right fine in here what we'll do display Flags and the flags Direction it should be row save sorry not rule column now what is the issue let's direction should it be row column okay it should be the default one so the problem homepage.tracer we have this oh my bad this snap should be out of this hmm okay now we have two child first is this one and we have space between so these are going to be side by side left and right cool save everything and after this let's have some padding and padding is going to be 15 and 10 15 from top bottom and from left right okay then we are going to have it fixed to position fixed and when we set position fixed we need to have the padding on the body so that that content can scroll through after this for that on this body do we already have some padding one body content padding top no we don't have this background color this is fine this is fine okay let me save it okay like this because we have position fixed so it is uh not going to uh have this space on the body so we need to tell the body that you should start your content rendering after uh this fixed portion so for that we need to have a so we'll say the height which is going to be 55 PX which is a nice height save fine and on body we'll say the padding top padding top it should be this 55px if we save it we can say this fine and we when we set position we need to set the anchors the left right or bottom so for this we'll use left right left zero right 0 so that it takes the complete horizontal width fine then we'll set top 0 so that it moves sticks to the top like this cool now on body we need to have that lighter color so here we'll say background color and really use the color what is the name of the color that is color main light color main light save and now we can see that lighter color and on this Maui nap bar we need to have the main color so we'll use the background color background color Main and Save fine we are saying something after this we are using this height here here we might need it somewhere else as well so it's better to have it as a CSS variable only so for this we'll name it never height so double hyphen this is a naming convention for CSS variables and here we'll have this 55px then we can use this variable at both of these places so here we'll say this where height of never and then padding top on body we'll use this same thing save everything it should be saved fine now in my neighbor let's have some Shadow so box shadow so that it gives the appearance of something like this is a native uh never basically the Box Shadow we will have 0 0 15 PX left right left top anchors then the radius and the color save and now we can see this nice shadow cool after this when this content is going to be uh crawled so it should be behind this so let me do one thing padding top for now let me remove this line what I'm saying save if you will see okay this is by default this one if we remove this color if this color is something else we can see this will be content will be we could say uh blend in with this so the better approach should be we should have the chat index which needed it on top always so we'll save it everything and now everything looks still same cool let's okay we can click on this it is navigating to save until it is coming back so we have something we'll see what is the issue cool we'll check it later and step by step so now we can get rid of this remove this fine save everything and we are still good cool so next we can see there is some differences from top and bottom it should be in center but it is not in Center vertically so this is because we have some margin the default margin which would step adds to H5 and this BTN so for that we can come here and on this H5 we can have a class m0 we don't need any margin from any side same thing we will do on this plus icon so we'll say m0 save everything and now we can see this moved a little bit here right next we need to increase the font size of this Plus so let's have f as one save and it is a bigger a lot bigger now so FS1 is for uh maybe mimicking the H1 size basically cool so we have this header is ready um fine next thing we will work on this page but before that let's yeah let's see this this top header this thing this is in this blue purple whatever this color is this is.net Maui color so the status bar on this Android this is of the default color but we need it as our app color right so if we see the sample app we are building we have the app so the color is different right the slider version of this color so we need to use this in order to do this in.net Maui what we need to do we will use Community toolkit so for that we need to add that new get package so we'll add a new get package that is community toolkit dot Maui Community toolkit Maui will install it Okay I accept and then we'll add it next step is to add the use Community toolkit in our Maui program.cs file here we'll add this cool now we need to add the um the behavior this is status bar Behavior we need to add this to change the color of the status bar and that we need throughout our app so the main container for our DOT net this is mainpage.saml this one where we have this Blazer webview where our complete Blazer app gets standard so this is the main container page we need to add that behavior here for that what we can do first we need to add the namespace and that we can copy from the docs or maybe from some other previous project let me copy the name space so this is this toolkit Navy space you can search for it Community toolkit Maui then you can check for the status bar Behavior for this we'll set content page dot behaviors and here we'll set status bar Behavior and here we can set the status bar color tool and this color we can have the direct color which is our main color but the better approach would be let's add those colors in resources and aware or resources Mouse is not working okay yeah so in resources okay we don't have it here we okay we'll have it in app.zaml here so we'll add those colors here so let me copy those colors um so we'll have these two colors main color and main color light the same thing which we have in our CSS color main color main light and color main lighters we don't need lighter in there but we might need these two so we are adding these two so now we'll use this main color light and the main page.xaml this status bar color here we'll use static resource and we can use main color light now after that we can set status by Style uh the content is going to be light content or we can have it as yeah let's have it light content only save everything and let's run it so this thing is mouse specific this has nothing to do with blazer web assembly this particular thing this adding Behavior apart from this everything is going to be kind of shared let's see if you are watching this video till now let's drop a comment that I love this project I'll check how many of you guys are actually following I love this project drop in the comment your app is loading and nice we can see this status bar color cool it looks great fine let's start working on this main section so for this we'll go back to our home page and let's get rid of this H1 and this H3 save everything and we are good we don't have anything here cool so let's start we'll have entire content in a div let's add let's call it page if we have some specific style to that page we'll add it in this page cool after this we'll have a bootstrap class which is div class container fluid to have the complete width and in here what we are going to have we will have a div class called 11 and MX Auto so this call 11 the bootstrap uses 12 grid structure so call 11 means we are skipping one column so one part of the page then MX Auto says that move the content to the center on x-axis that is horizontally so we will have half column width left from the left and half column from the right so it will be 11 columns in the center fine save after this we are going to have our heading that is all loads and all that we will have a div class here in this we'll have let's say h 2 and here we'll say all notes save we can see this now on this div let's have some spacing from the top so we'll use margin top mt3 fine after mt3 we will have after all nodes we will have those if you remember we had that grid layout right that layout Chooser we can use a grid layout and we can use list layout so we'll have those icons and now when I set these icons for the icons in this app I am going to use the Box icons so you can simply search the Box icons.com on the internet then you can come here and you can download 2.1.4 box icons I already have it downloaded let me add that to our project and because we are going to use those same box icons for both the projects so the best place is going to be add those in this common dot components project in triple W root folder we already have fonts Ubuntu here we'll add the Box icons font so when we say fonts I copied the fonts in the common fonts folder box icon see your tttfwfw all the available options and then it gives us the CSS so box icons.main.css I added this in our CSS file right now we need to add this CSS in our index.html page so for that let's go to the Totten my project triple W root index.html We'll add that here the same way we have added common.css we'll use the Box icons content then the assembly name CSS and then we can simply copy the name and we can add here so box icons.min.css fine let's move it to the top fine like this cool save everything now we can use these box icons inner page basically so for that what these box Cycles gave us so we can check for any uh icon we can click on it and then we can see the font so it gives us this I class bxbx child so this is the HTML we can use in a razor components in order to render the icons right so you can check those you can close it fine here what we'll have after this all loads first let me run the app so that we can see the design side by side fine after this all nodes in mt3 we will have those icons so for that let me create a container here so let's say filter bottles filter btns and here we'll use those two buttons so button type button class BTN BTN default and in this we will use our box cycle class this is going to be BX then BX grid Alt like this save it and now we should see something we can see this one after this button next thing let me copy this button add one more time and this time the class is going to be X menu this is for that list like this now we need these two icons side by side of this all nodes so we have this container of both of these item here we can say d Flex display Flex now we can see this here next thing we need to have this on the both corners so we can say justify content between us justify content between fine and align item Center so that these are vertically centered or not sent let's move this to end cool save everything now these icons are very small so this gives us BX SM classes right so we can use the same thing for both of this b x as n cool now we can see these two things fine we'll add reactivity and selection later but for now we are just having the design after this we will have uh one horizontal line so after this div let's have that HR horizontal rule this is HTML save we'll see it here in black color but we don't need this in Black so we'll add classes first is text white we need this in white color cool then we don't need the margin okay we cannot see it right now but we will be able to see it uh when we add the content to it fine after this now we are on this screen so if you remember we had that single item here that single box if we do not have any note then it was getting displayed with the plus icon and then the add a note button so that was a card so we'll design that card now so when we do not have any node then we'll have it here like we'll have a div let's say class and we'll say empty nodes let's say box wrapper fine and from here also we will navigate to the same URL so let's have this nav link here as well we'll design it save like this we can see this plus icon here now let's add a couple of classes on this nav link so we don't need this all these classes remove everything we'll see this thing here now let's add the classes to this first thing we need text Center then we'll have a box this will add class to this thing next thing we need text decoration none so that we can get rid of this Fender line then we'll use display Flex justify content Center let me minimize this file justify content Center align items Center and we need this as Flex column save it we are adding all these so that we can have the plus sign and the text so let me remove this come here and here we'll have two items first we'll have that plus sign so let me add the spend for this then we will have a label label here we'll say add a note let me save and we can see these two things right now let's change couple of things first let's add The Styling for this empty note box wrapper and this box so this is going to be in common .cs this thing and then products dot box and let me save everything fine on the empty notes box wrapper we'll have the display flats for this justify content centers you guessed it I liked its like content Center and align item Center Center then we'll have a height and this is we are going to have it relative so we'll have it 100 VH that is the viewport height after this we'll have the width which is again going to be 100 VW so this is viewport width and any overflow we have here we'll simply skip that so we're located save everything and we can see it here but this is not this is not that good right 100 VH height but we have a padding of 55 from the top right okay so what we can do we can copy this thing go to specific Maui specific classes and here we'll add one thing which is going to be the height will set this height Kelsey this is the dynamic calculation in CSS so we'll have 100 VH minus the this variable padding top right this variable let's use this here save everything and it got uh to the top right it's simply moved cool save everything and now let's come here now for this box first we'll have a background color of a variable of the slide so in this case we will not see anything then first we'll have a box Shadow so this is going to uh display something 0 0 5 x 5px radius and color is going to be white now we can at least see something right cool after this let's have a padding and this padding is going to be 8px and 16px fine 8 and 16 after this what we'll do here we'll set a mean height on this so that it look good let's have the height only not mean height we are fixing it to 250 PX save and now we can at least see something after this we'll have we'll add other or maybe let's add everything right now only so this box we are going to use this box class for all our notes card as well right so some things might not make sense right now but these will make sense once we use this box class for other things right right so for overflow y we are going to use Auto that it will add the scroll bar and let's have some radius Corner radius that that is border radius 5 PX save and we can see this radius after that for the Box we'll use display Flags only cool and then selects Direction this is going to be the column next we'll have position relative and then we'll have this transition and we cannot see this transition on mobile device so this is not for Maui this is for webassembly so where we have the uh basically we'll use this for hover hover effect so let's use all is in and 0.3 as this is for apply this transition using is in for all the properties and it should be applied for 0.3 seconds so we'll see when we'll uh use this on webassembly side then we'll see it after this this is the common box style but what if this box comes inside this empty notes box wrapped if this comes inside this then we'll add some additional Styles and that additional style is going to be will set the height and width we'll set it fixed to height and width same 250 PX and this is coming in this case so we can see it like this cool and let's add the hover effect on this which will be used in webassembly side but let's say have it slow power we can use this when we long press in the mobile but that is not that good ux for that we'll use a box shadow of 0 0 10 PX basically we are increasing the Box Shadow and in this case we are removing the Border radius by zero because the default is five it will be 0 when we'll hover over on this box cool so we are good with these now let's go to our homepage.razer in here and let's do one more thing let's add one more class on this one so we'll say add note BTN this class save everything let's go here look it broke we'll work on this first add note BTN let's read on the app then we'll add The Styling to this add nodes uh BTN so app is here now let's work on the styling for this so add note BTN here first thing we'll use cursor as pointer this will again will be used in Blazer web assembly side then color black the text color basically now we can see this pink and black and we'll add the same transition to this as well save and that comes after this add note BTN inside this we have one icon and one label right so let's go here and let's add classes to these as well here we'll say icon and here we'll say dot label so inside add note vtn when we have icon we'll say font size so this will become bigger this plus icon then we'll say font weight bold save so this is bolder now and that we will remove the default styling by padding zero and let's have opacity of some light opacity opacity 0.6 save and we can have it lighter find similar thing we'll do for label so when for this thing when dot label comes under this button we'll say font size uh 25 PDX and the same opacity that is 0.60.6 save everything and now we can see this is a bit bigger and some light color cool after this we'll have that hover effect if we long press it here or we are on Blazer webassembly the browser then we'll when we are hovering over it we want this to be darker so for that what we can do let me copy this thing add here so here we can see when this dot label comes inside add node button and we are hovering over that then what we'll say we will have opacity of 1 and we will have the color as black right if you do this now we can see this is black but this is light blue so we'll simply copy this label and do the same thing for DOT icon dot icon save and this is default if we long press it we can see this like this so the things are working fine now we are here and we can click on it and it will navigate to the next page right now we are coming back that will see what is happening but it is working so this is works and the same way this plus works right so we can go there it comes back we can go there it comes back we are good with this add node button now next thing when we are clicking on this or maybe uh okay we'll work on the listing the nodes later first let's work on the next page which is the save uh save note page basically so let's save everything I saved everything and now we need a new page and that page is also going to be shared so in this Pages we'll create a new Razer component and that we can call save note or something like this we'll say save note page save note page add and we are good first we need to have router write the red page we'll use this save everything and let's have H1 right now we'll say save page save everything run we are here let's click on it now we can see the save page cool so we are on the save page now we need to have the same uh navbar but the content is going to be different so first let's work on the nav bar so we can simply copy the number from home page so we have that here like this like this at the rate instead of username we will have let's say save node save everything and we can see this right in this view we'll have three sections first we'll have that cross button on clicking on that we'll simply come out of this page basically it will behave like we are navigating backward then instead of this plus icon we'll have the check mark and the save note will have this in the middle of the section okay so first we need to have that cross mark so let me copy this Plus will come here and instead of this plus icon we'll use box icon so why class BX we have b x x and then bxsm Nikon let's save and we can see this cross and save node then Plus right so we have this save node we don't need this div you can get rid of this tip cool save note and then instead of this Plus we will have the check mark and that also we'll get from the box icons Pi class BX BX check like this save everything and we can see the things now cool again we have this inconsistencies we can see there is smaller space from top and large space from bottom so on the snap link we have m0 let's have adding 0 as well FS1 if this one's right let's use we already have BX at some right so the same thing we'll use in this bxsm and we'll have M 0 and p 0 and on this H5 we already have m0 so this is fine everything looks fine now right now we have this this is something hmm so we have BTN between okay do we need between classes no right okay we can get rid of this BTN so let's have it text white only if we save it everything looks fine okay let's have the text decoration and as well so let it does not get applied when we hover over it so tax preparation none save everything and we are good the first one do we need it no we can get rid of this m0 no that's why it be 10 default okay now we'll work on this page right we'll add the form here so before the form what we should do we should have our node service ready because now we need that service so which will which we'll use to save the note edit the node create a new node and get the list of the nodes and that is going to be in common project where we have services where we have our auth service there we'll have a new class which is going to be our nodes service nodes service note service fine and in this project we'll have our models as well so models will have a note model basically so let's create a new folder we'll call it models and we'll create a class here we'll call it node public class note public class node and let's add some properties first will have ID and we are going to use guid for this the default value we can have geoid.mp which is actually default but we are trying then have the title of the note then let's have a description of the node description after that let's have a date Time created on when this note was created let's have a default value for this date time dot now and then we'll have uh label daytime property which will hold when this node was modified cool now let's have some data annotations here so we'll have required notice required and the max length we are allowing is 75. that is more than enough for title then description this is not required so we can have this nullable string but we will have a max length check let's have it something like 250 characters clean and we are good with this note class fine now we'll work on our node service clean this up fine change this to public cool and now we'll have couple of uh methods here to save the nodes get all the nodes and we add an update basically and deleting nodes we'll have all those methods here so first thing let's have public async task I enumerable of our note which is this node let's say get all notes fine so we are going to save our nodes using our storage service so how this is going to work on Blazer web assembly side it is going to be saved all these nodes are going to be saved in the Blazer sorry browsers local storage and in dotted Mouse site these are going to be saved in browsers mobile devices Secure Storage so this is not the correct place to store in Mobile side they should be in sqli database but for now I am going to use the same centralized storage service and I'm going to save these nodes in Secure Storage if you want a next part of the series in that we can enhance this app and I can save these notes in the sqlite database in the mobile side instead of the Secure Storage do let me know in the comments drop comments if I got enough comments stating that we need uh sqlite database for saving the nodes in the dot and mouse side then I'll definitely create an extension of this project this video where we'll use the sqli to store the nodes frame so here we will inject our storage service which is I storage service storage service storage service fine now we'll get our nodes so the data we are storing in the storage this is going to be serialized because local storage and Secure Storage both of these supports only string data so all there's going to be serialized nodes so we'll get the nodes from Storage service dot get async this method we have and we need to provide a key and for key we can go to app constants and we have the storage keys so we can use this we'll add one more constant we'll say nodes and we can name it whatever we want the value and here we'll use app constants dot storage Keys dot nodes and we are good we pass the data we get the data now we'll check if the serialized nodes actually had some values in it so we'll use string dot additional or white space if the serialized nodes had some value then we'll deserialize that so we'll say one nodes equals Json serializer say realizer which will come from system.txt.json then we'll simply deserialize a numerable of nodes serialized nodes fine and we will use uh centralized Json serializer options so that we can use those for deleting fetching adding nodes so let's use private read only Json serializer options Json serializer options and let's have this default right now we can use this we can add the other values if we want now let's follow the same approach we followed in other services like this we'll initialize this in the Constructor fine so when we are deserializing we'll pass the second parameter which is this Json serializer options fine so now we have our nodes in this nodes from here we can return the notes cool and what if there was nothing in the storage in that case will simply return an empty collection of nodes so enumerable dot empty note right here we know this is not going to be null so we can use this null for giving operator fine so we have get all nodes after this we'll work on creating and uh editing the nodes basically so let's add a new node so for that we'll say public async task add glute bank here we'll use node node as a parameter now we'll first check if note dot ID is guid.mt that means we know we do not have the uh we do not have any ID that means we are creating a new node this is a fresh new node so we'll set the ID using guid dot new guid we are setting the ID then we will get all nodes so this we can get from awaiting this guy at all notes right so get all nodes async let's async so we'll use get all nodes async we have this and we need to add our node to this one so we'll use the tool list here we have notes list now after this we can simply add a note to do this so nodes dot add this note this new note we added this and then we'll simply add we'll simply update the nodes collection basically we will use storage service Dot save async and here first we need key that we know we have app constants dot storage quiz dot nodes and then the value is going to be this notes we are going to serialize it so we'll say serialized nodes and we'll use Json serializer dot serializer nodes and Json serializer options the default and then we'll use this serialize sorry serialize notes Here like this and I'll wait this so we are going to need this thing multiple times when we are updating deleting all so let's extract this out to a separate method where we'll say private async task and let's say save notes and here we'll get a numerable of nodes and we'll do something like this innumerable of node of nodes and we will do this and after adding these two nodes collection we'll say this a weight save nodes and this sync a sync async and we'll pass this nodes collection updated nodes collection this should be add node async file after adding let's work on the updating node so we'll have public async task task will say update node missing here again we'll get a note and we'll check this time we'll check the opposite of this if this is not empty that means node.id has some value that means we already have this node so we'll update it for that first we need to access all the nodes which we can use that whole net all nodes async then we'll find out the node to update that we can get from this notes collection from here we'll access the first or default node and we'll simply say n dot ID equals note dot ID like this and if we have this node to update if this is not null we have this this is Edge case but still it's better to have this condition here we'll update the node so node to update dot title will update it using node.title then node to update to update the description and edit and then node to update dot modified on this will use date time dot now and this is default but for this also let's hides this node dot created onto datetime.com not UTC now we are using now fine and here we have updated everything now we will simply use a weight save node says sync and we'll pass this notes collection and it will be updated cool now let's work on the third part which is deleting a nodes so we'll say away tracing task delete node async and this time we can simply have the ID we don't need to have the complete node first we'll check if this ID actually had some value this will say if this is not guid DOT empty that means we have this ID then we will simply check if we have this node so we can do this approach and yeah let me copy this two lines and get all nodes async this time we'll say node to delete and this time we'd have direct access to ID here we will check if note to delete is not null then we'll simply remove this nodes from our notes collection and because this is innominable we cannot use this so we will need to change it to list we'll say to list and then we can use the remove method and node to delete after this we'll simply save the nodes collection back to the storage so we have saved it as well truly everything looks fine now we have all these there is one case missing which is which is when we will open the note in edit mode we need to get the node details for that we'll say public acing task note it could be in a label because we can pass some invalid ID from the from mobile it is fine but from Blazer web assembly from browser it will not be fine so we need to have it like this here we'll say get note async and we will have access to guid of ID here first we'll check if ID is not equals guid dot empty that means we have some ID if that's not the case we'll simply return null now we need to have access to that particular item so for that first we can have our nodes equals of weight get all nodes async and from here we can return notes DOT first or default and Dot ID equals equals ID like this we'll have access to this node okay so our note service this is fine we already worked my storage service so this will work out of the box now we can register this node service in our dependency container right now we are working on dot net Maui only so we'll register it here so let's have it it will be used on all the places so let's register it as Singleton only add Singleton like this notes service I have not used uh interface for this but you can use if you want cool we have access to node service now we can inject this node service directly on our save notes page and our home page cool so we'll work on saving the nodes first and we'll work on eight after some time so it's been more than two hours two and a half hours actually so just you can take a break I'm going to take a break and I'll be back soon you will not see that break I am going to pause the recording then I'll resume the recording when I'm back okay so till the time you can drop me in the comments if you are liking this video if you are following along or you are simply watching the video right now and you will try to implement all these later so do let me know in the comments hey so I'm back now let's start designing this page first we'll have our model because we already created note model so we'll use that model here so let me have it as private let me stop it private note and then node it is coming from our common dot models so let me add it to the imports.razer using common dot models Point save it and now we should be able to have this note here private node station Imports razor oh my bad I added it to the Maui but this page which we are working on this is in this common dot component so I need to add it to Common dot components I'll use it here and now we can have this node and let's call it model we will have default value fine now we'll use this model so uh this check mark on the top header so it is going to be used as a submit button so if we we are using that as a submit button we will change the snap link let me run it so that we can see it designing cap is here let me navigate to the save node page fine and now we will change this nav link to submit button for that let me add a button here button type submit and then we'll use the same classes vtn BTN what is happening BTN default and text White and in this we'll use the same I this box icon as check mark and then we can get rid of the snap link save and everything should be the same fine now we have the submit button then we'll have one more submit button when we'll add our fields and all those so the submit button it should be inside the edit form so that it can trigger the form submission so what we'll do here we will have an edit form let me add this using in the import short region so that we don't have to add it on the page and we can use this throughout this project so we'll say at the reducing this continue editing go back we can remove this edit form and this edit form it will contain the complete app for this page basically so when we use edit form we need to provide a model and in this case model is going to be our model this node model and after that we will use on valid submit where we'll provide our method to save the node so let's have it private async task save node is sync fine and here we will call it save node async pool and we have added data annotations so let's add the data annotation validator here to force the data annotation validations basically fine now we have this header and after this header now we need to have our complete form so for that what we are going to do we will have a div class container fluid complete width then we'll have a div class row and on this row we will have the complete height will take this complete height so we'll say main VH 100 this class is coming from bootstrap which means many minimum height for this div we need it as a viewport height 100 percent okay and now we will have continue editing let me re-run it okay go to save node page fine in here we'll have of class div class and here the classes I am going to use will use a common class which will be used in webassembly and this mobile as well so right now all these classes will not make sense but when we'll see these four webassembly browser version then these will make sense so bear with me so we'll use xxl5 call if this is Excel will you fix if this is MD medium devices we'll use it and if this says SM we'll use 10. these classes we need like this after this we also have a class mt3 add margin top 3. fine inside this now we'll have our complete form the title and description and R button so for that we'll have a container basically so Dave class let's say mobile home container and in here we'll have a complete form we will start it we'll use Dave class and B3 margin bottom three this is the way we create form elements using bootstrap okay and in this I am going to use the floating label uh design you can check the documentation on bootstraps official website so I already have it so I'm going to use it directly leave class from floating this is the main class inside this we will have our input text and for this input text we'll bind its value Find value with our models title so that is going to be model dot title model dot title fine and then we'll add couple of classes here and the classes are going to be form control border 0 rounded zero and we'll use let me open this like this rounded zero and we'll use a bigger font so that is going to be FS oh my God f as poor and close it save it pound of malformed put the issue with this input text is there any issue with this bind value no I don't see any problem let me rerun see remember when I was starting this video I told you that this hot reload with dotted my blazer hybrid it just it's worth some time now this is the time fine we have this input text here after this we'll add that label for that we can have that label directory here and we can say note title no title like this and dot dot dot save it and now we should see the note title okay cool after this on this uh box this input text what we'll do after fs4 we will use a background color and that BC color is going to be BG okay we should have one more class in our common dot CSS so we have these colors we'll create helper BG classes with this color so we'll say BG main dark not dark BG color main or let's say BG main only BG main where we will set this main color so we'll say background color you are this one and we'll enforce it then let me copy this two more times copy paste paste and we'll use the same approach we are using the variable name so light color main light and then lighter Main and lighter save everything and let's come here and here we'll say BG Main lighter save and we can see this now tools after this what we are going to do we are going to add the next uh description box for that let me copy this MP3 we'll paste it here and this is going to be input text area input text area bind value is going to be uh model dot description the classes these are going to be form control is fine border 0 rounded zero we'll set it fs5 the background color will use the same color border 0 but we'll have a border from bottom we'll say border bottom the label will change it to description description save it we should see this description after this on the text area we'll use rows 5 which is for showing the bigger text area but with this floating label this does not work so we can have explicit styling so we can set Min height to let's say 250 PX save and now we can see this node description here like this okay fine after this let me add the placeholders so we'll use Place holder on the Node so we'll say enter node title and then on this text area or this description we'll use placeholder and we'll say enter node description this will be done save everything and we should be good now and we can see this thing is working right floating label is working pool fine now let's add if we click on it nothing will happen it is this red color outline will change it we don't want this we will change this but before that let's have that validation message so we see that validation kicks in and it is invalid field because the node title is required but we should have that validation message as well so for that what we'll do here in this div class mb3 after form floating we'll have a small tag and in this small what we will have we will have this validation message and it requires a four parameter and here we'll simply pass underscore model dot title add the validation message for this field and on this small tag we'll add the class display block and that's danger which is going to turn this tax in red color save everything and now it will do this we can see the title field is required but this is something which is coming we'll see it what is it copy and we'll do the same thing for our description save everything continue editing and we should be good now now next thing is this outline this red color so this must be coming from the default CSS and we have this if the field is invalid it will show outline 1px solid red but we are using we are not using borders for this so what we can do either we can simply remove this let me comment this out first oh we can save it continue now it is fine we cannot see that and if we tomorrow if we want to change this we can have the Border color basically we'll set the Border color this and if we are showing the Border then it will automatically going to be applied and here also we'll say border color and this red save and we should be good now cool after this we'll add our submit button which is going to be the save button so here we'll say after this div class mb3 this description box we'll say Dev class mb3 and we'll have a button pull width button basically so we'll say button type submit button type submit and we'll say save and on this we'll add couple of bootstrap classes for BTN BTN primary and now we can change the background color to our darker color continue editing and it is not working Let Me Reason okay we are here we can see the save button and this is something okay save button also has some default style which we do not want input will put this no add note between what we don't need this we need BTN BTN primary Main after this we need to have this button for full width for that on this mb3 we can set the display grid D grid so it will take the complete width tool we have this thing now this red dot this is coming from somewhere and from where it is coming is it coming from the spin class Hotel B export block oh it should be d block d block d block save so this is basically for display block fine now it is fine so we can save it it will not allow us to save and if we provide the values for both of these then we can save it now it will go to this save note async method so the design is fine now let's work on saving this node cool so in order to save it we need to inject our node service what was the name of a that means we need to add the name space for that as well and node service is in the Navy's face this notes mobilizervation.com.services will add this to our common components we Imports underscore Imports so that we can use that direct link fine we are here we inject node service and we'll call it notes service only nodes service save everything fine now we'll try to save it and when we are saving it first let's have a try catch cool after this we need to check if this uh this node we are saving if this is a new node or we are editing an existing node right so for that first we will use the save note only so let's directly use a weight node service dot add note async and we need to pass the node and in this case notice our model fine and when this is successful then we'll simply navigate user back to the previous page and in order to navigate we need to inject navigation manager so navigation manager navigation manager and we can use this navigation manager directly here we'll say navigation manager Dot navigate to previous page which is slash home fine and if we got any error here so what we can do we can simply show the error alert and in order to show the alert we know we have a service for alerts so we can inject that we'll say I alert service and we need to use this as well on the underscore Imports so that we can use it throughout this project I alert service alert service and now we can simply show an alert here so we'll say alertservice dot alert racing and here first thing we'll display a message we'll say error in saving node please try again something like this please try again and we can have the error description as well so after this we'll have a new line and then we'll show ex Dot message fine then the title is going to be error and we'll await it we are good we don't need this through now cool so it looks fine we can work on it but it's always a better idea to show some indicator that something is happening so that loading icon or something like that so that we can see the user can see that something is happening there so for that we'll uh Implement a flag for that let's have it as private Bool and we'll say let's say is busy or underscore busy this is fine the default value is going to be false because we are not not setting it and when we are trying to save the node we'll set it to true and if we return from here then we don't need to do anything so we should be good and if we got some error then after showing this alert we'll set this back to false because user is going to be on this page only so we need this page to be interactive after showing this alert fine and again you see this is again freaking out okay now we need to use this underscore busy flag so we'll use this we can modify this button so we'll say if it is busy store some different button and if it's not busy then show this button okay so the button will be same just we'll change the type to button and we'll add disabled class and attribute wheel at both and then we'll display instead of this save or maybe we'll have the same text but we'll have a loading spinner which is coming from bootstrap so we'll use pan you can get it from bootstraps official website only so here we'll have span Plus spinner border spinner border SM Ile and after this we'll have saving this thing so right now let's have some artificial delay after this we will say outweight task dot delay and let's say 2.5 seconds so that we can see something is happening and same thing we need to disable this button as well the stop button this check mark so we'll do the similar thing there let me copy this thing and we have this box this button button type submit so here also will do if busy then do something and if it is not busy then do this fine let me paste this copy this paste this and add this and this time we will not have this text here and with this button type submit we will change this to button button and add the disabled attribute fine now let's see if this works save everything and rebuild and apply changes okay go to this page first we'll try to save it we have these errors We'll add something and then we can save it and you see at both of these places we can see that that spinner and after saving it it went back to the this Main home page cool so we are done with this save notepad creating a new note for mobile now next thing we will work on displaying those nodes on this screen on this home screen so let's go to home page and we can inject our node service because we will patch the node from this node service only node service fine now we'll use this node service in our code block so first we'll have a flag private Bool let's say is fetching patching the nodes and we can have a default value true because we know whenever we are coming to this page we will simply fetch the new nodes in any case always basically so we'll use that fine so let's patch this we will override our own initialized async method and in this method we'll have a try catch block and in try we will fetch the nodes and when we are patching the nodes we should have a list of nodes here which will display we can have private enumerable node and we will have this type underscore nodes with a default when device empty nodes enumerable okay so we'll use this underscore nodes to show the list of nodes basically so let's patch the nodes we will say nodes equals a weight node service Dot what was that get all nodes async find tool so we have underscore nodes now and after fetching the node we will simply say the is fetching to false or maybe we can have this Edge fetching false in finally block because we want to set is fetching to Falls in another case if we got some error or in the patching node was successful right cool and if there was some exception we can simply show the similar alert we are showing in the save note page so let me copy it paste it and here we'll say error in patching nodes something like this and then we can display the error message fine and we need to inject the alert service so let me copy this line from save page and we can inject it here as well rebuild and apply changes tool so now we have underscore nodes collection and we have this underscore is fetching flat so we will use these two to show the that loading indicator and the list of nodes fine in this let me come here inside the page after this all nodes and this section all notes everything is fine empty notebook okay let me add it here so here first we'll check if we are fetching the nodes if we are fetching the nodes we will simply show unloading indicator here for that what we can do we can simply use the same loading indicator or let me take class D Flex justify content Center [Music] align item Center pan margin top 5 and in here in here we are going to show the one indicator or maybe with that let's have some text as well okay so what we will do here we'll say Dave class spinner and we'll use a different spinner so spinner grow and then we'll have text let's say dark and then it is going to display one spinner if we save it and if we have some delay a weight task Dot delay and let's have a delay of five seconds save everything go to the next page okay we'll come to this page we can remove that indicator from there right now we can see this indicator you can see loading it was loading so let's do one thing we are designing it so let's have it as false save next come back so that we can design this basically tool so we have this indicator after this indicator let's have some text as well that what this indicator is doing because we'll have we'll fetch the nodes on this screen we'll delete the nodes so we'll display the actual message that what this loading indicator is for are we patching the notes right now or are we trying to delete some note right now so here we can save patch this p and we can have in this case we will say fetching notes like this save it rerun and now these are side by side but we need these uh vertically so the patching nodes should be in the next line so for that we can have one more container on this text this spinner and P so we'll have a div class we will have display Flex day fine and here we will have these things let me save this okay now we'll change this the direction to column Plex column and now these are like this next thing we'll uh justify these justify content Center and then align items Center fine so we have these two things now let's add some Shadow as well so bootstrap gives us some Shadow utility classes so we can use Shadow LZ and now we can see this and it is very narrow so let's have some padding from P3 cool so we can see this and this is looking fine now right yeah cool and after this if we are not fetching then only we'll display the next part of the screen so we'll have this else here we'll say this like this save and now we can see only this fetching nodes here tool now one thing we might need this loading section at multiple places so it's better to have it as a reusable component right so let me copy this and stop the app because we are going to add new folder and files so in this common components project only we'll create a new folder we'll call it components so we'll say components and in this we'll add a new razor component we'll call it loading component or let's call it loading only and we'll add that design here cool now we made this but this fetching nodes this text this could be different right as I already mentioned we will show this loading indicator when we are trying to delete a note then it should be deleting note right so and this is a reusable component so we can have one parameter and we can access we can get this text from the consumer of this component so for that we'll have a property here of type string and we'll say let's say loading text and we'll set the default value as loading and we'll add parameter attribute to it because this is going to be used as a parameter and then we can use this directly pair like this loading text we can save it and these components uh in this using statement we'll use here so we'll say components dot components okay this is different but these are reusable components basically we can name it shared or let's have it like this only [Music] fine now we can use this loading indicator instead of this hard-coded thing what we will do we will use this loading component like this and we can pass the loading text from here in this case this is going to be fetching nodes so we should see the same thing we were saying before let me run this and we can still see the same thing and we can change this so that we will be able to see the new text right you can see this so this thing is working cool now when is fetching is false we will come here and this empty notes box wrapper this should come only if we do not have any node so here we'll have a condition if underscore nodes dot any if we do not have any node then only we'll display this empty Knox nodes wrapper if that's not the case now we are at the place where we need to show all our nodes let's have one Loop here right now we'll design it but for now let's see if we can display those so we'll save our node 10 underscore nodes here let's have label at the rate node dot title save everything and let's remove this pause and it's let's rerun the app app is loading loading fetching nodes after five seconds we should see these texts right and let me add a br here because we have multiple nodes but we are seeing only one right I added BR now we can see we have three nodes one two three right now next task is to design this section design these nodes foreign first we will have a container we'll name it I will add a class container fluid container fluid and then in this we will have 13 plus row and then inside this div this class row will move this for each Loop and now we'll design our uh the main section basically so here it will first create a container and that is going to be div and here we'll have call sn6 call md4 these are for uh web assembly basically and for our mobile thing will have all six so the half of the screen okay then inside this inside this we will have our main container with class box so we already added the CSS for this box so we'll use this only and in here first we will have a div container or title from title we'll use at 6 for that at 6 with m0 and in here we'll say node dot title save it let's see how it looks and it started to look great let's create one more note with some actual value some long title for some long title so I told to check the home page or Cy let me copy the same thing now let's have it without description patching nodes and we have this now this is a breaking tool the other lines it is now three lines but if you remember in a demo app the final app they should be in single line only so for that on this H6 we can add one more class and that is text truncate like this so it will be truncated and it will add these three dots so that it indicates that there is something more to this string fine now after this HR at six we'll have one HR tag to add a line and it bro let me rerun foreign I think we should remove these delays now this one and let me go to save nodes as well and we'll remove this delay as well fine save we have this HR now after this HR start adding the description so inside this together box after this div we'll have an operative okay and in this div now we'll create a class here we'll say node uh description wrapper like this and then now we will have two conditions if you remember if we don't have description then we'll show that plus and add a description button and if we have description then we'll simply display the description where we'll have a condition if not string dot is in a lower white space dot dot description move it aside fine if we can then do something and if we don't have the description then do something right so when we have the description so the description is not null or empty then we'll display the description we will display the description in a p class here we'll say note dot description fine and we'll add a class here let's say let's add a style here we will save font size 14 page fine save and we should see the node description for these three items but this one does not have the description so this is not coming up we'll add else case for this particular one so here we will have one nav link because we want to navigate user to the to the next this save page basically the in the edit uh section we want to allow user to edit this node so for this nav link first we'll have hrev and this is going to be for now let's have it at save only but it should be changed to edit link and in here we'll have couple of classes the classes are going to be text Center text declaration none then D flex and we had that add note BTN class we will have justify content Center justify content Center will have a line item Center we'll have Plex column we'll change the direction of this Flags and then in this nav link we'll simply have these two things fine if we save it we can see add a note now the only thing is we'll change this add-on node to add description so we'll say add description add description now we'll uh change the font size of these two items so for this label we'll have fh6 font size same as H sticks and on this icon let's say fs4 fine now we can see in title we can see a description and we can click it it will navigate to the save node this is not correct right now it should have the edit form with the title pre-filled we'll do this and then okay to go back we should work on this cancel button this cross button on clicking on this it should navigate to The Back Page the previous page the list page basically we'll use this back button and it is not working let's add something here we saved it fine we'll see all those columns one by one now apart from this uh right now we can see these are the vertical spacing is not there so we should have that vertical spacing okay that will have but before that if you remember we had those uh patterns and the last modified date and time here so let's add those first so after this note description wrapper we will have one more deal here let's say actions Maybe and in here first we'll have one HR to have some spacing uh not spacing that line to have the to give a separation look basically checking out State and now we have this so this line this line we are talking about but this should be at the very bottom so what we'll do on this div the second div the wrapper of the description on this we'll add a class we'll say the class is going to be Flex group 1. what it will do it will work as it will try to take all the available space the parent is box which is a display flex and it has right now three item so first item will take the space what is required for its content same goes with the third one and for the center one the middle one we said Flags grow one so it will simply acquire all the available space cool now in this actions after HR will have one div and this day we'll have display Flags to deflex and then inside this we'll add other classes but before that let's add the content of this so here first thing we need to have the date time last updated date time so for that what we will do we'll have a small tag here okay and in this small first we'll have the that clock icon and that we can get from box icons so the class is BX BX Time 5 this is the class we can use if we save it we should see this little clock right after this we'll add the time basic limited time but for that let's have one more small tag and here we'll check if we have some value for modified on if we have some value in modified on then we'll use this modified ohm so we'll say note dot modified on dot value Dot tostring dot two string and we'll say d d m m yyy and h h m m if that's not the case then we'll use node Dot created on so this is not nullable so we are sure that there will always be a value in this we can say two string and then we can use this format and if you want to have the same format throughout the app we can have some centralized service some great time service or something like that and if we are not willing to do that the simplest we can do we can have this format in our common constants so we can go to our app constants and in here we can have a direct constant public cons string I will say date time and something like this and we can have it here like this and then we can use this date time format okay time format will come here we'll say F constants dot the time format and same thing we can do like this um okay so we should be good now save everything and let's run it so it's here next thing we will add those menu items here those action icon basically so for that after this div D Flex after this uh small tag in add let's have a div the container deal for this and in this day what we will do we'll simply have a button of type button and we'll add classes BTN p t n B T and S M and then inside this button we'll have one box icon class which is BX and BX dots vertical around it this is the class save everything and now we should we should see those things where is it it should be here somewhere we are not able to see it and y so VT and BTM s M we have b x b x dots vertical rounded oh you vertical founded yeah we can see now this is the thing so uh this is breaking to the next line because the space this button is taking this is too much so we should have a smaller button so we cannot use BTN SM we should have something like BTN access which is which stands for extra small but this class does not exist so let's create this class and we should add this in common components because this is going to be used across the app we could say BTN access and we'll use the similar approach bootstrap uses BTN smlg all those classes so we'll have a smaller padding zero point REM then we'll use font size of 0.6 REM and we'll use border radius border radius 0.15 Ram find save and now you can see this thing but this is a little bit smaller we'll do some other things as well but for now we can see this let's go back BTN axis okay so we can see something at least paytm vtn access now for this we can use one class from box icons to BX s like this and on this date time let's try to make it smaller as well and this date time so on this small we can have the style we'll say font size and we'll say let's say 12 bits fine now we should have the spacing between these two so that these can be side by side uh around the corner basic line it should be on left corner and this cycle should be on the right corner so with d Flex we'll say justify content between it is going to use justify content space between like this and vertically it should be Center aligned so for that we'll say a line items and we are good we can see the things now fine now we need to add spacing between these vertical items basically so this spacing between these two but this should be same as this Gap right so this Gap bootstrap handles this using one CSS variable so we are going to use that variable only and what we'll do we'll go to common.css and in here what we'll do we'll create a class we'll say call let's say Gap y or we can have just call Gap fine and for this no we can have we should have called Gap y so margin top will use then the variable bootstrap uses that is BS for bootstrap gutter this facing is called Gutter and then X so this x axis Gap so we will use the same gapping for this so we can use this and then this call Gap y we can use this CSS class home page we should add this on the main column this one so we'll State call Gap Y and if we save it we should see this structure so we are good with this move right okay cool now after this we want the last item to be the the Plus this one we need this to be the last item so we can copy this thing and we can paste the same thing after everything inside this row after this four each like this the only thing we are going to change we need to have these classes and if we save it we can see this add a note button which we need fine so I think this page is fine we'll work on these options later but for now let's have it like this only cool now next thing we will work on edit note or maybe before that let's work on this cross button so when we press this cross button it should navigate us back to the previous page so for that let's go to save nodes page and on this we have this bxx okay it was not going back because when we click on this x then it will be direct to the same page it will be on the same page but we need it to be go to the home page we'll save it and now if we click it let me rerun okay let's go to this page and click on cross and now we are coming back so this is also working fine now let's work on this edit uh edit node section first so for that what we can do let's on this we need to have one more route so that because when we'll edit a node we should have the values populated whatever values we have right so for that we need to have the details of that node and when we are using this routable components we can have something like slash sales slash then we'll have our node ID note ID or we can call it just ID so using this we will be able to Cache the get the ID and we'll have it in a label that's because for the first case it will it should work so we will have two routes for this slash save this is for the first create a new node and the second one is for editing a node now we need to access this ID so for that let me collapse everything fine we need to have parameter here to that parameter it should match the name of this uh this Dynamic route value the casing does not matter the name matters so and the ID we know this is guid and we can this is in the label so we'll use this like this the next thing we need to add parameter activity so now this parameter this ID this property this is binded with this route parameter this ID so we are good with this now next thing so we need to have the note ID so that will use a computed property so we'll say public guid note ID and there we can say guid dot right parts and this is 4 if we pass some invalid uh invalid guid to this so in the it does not matter because we cannot pass the URL we cannot see the URL Bar address bar we cannot add anything but when we will go to the browser Blazer webassembly version there we have access to the browsers URL address bar and there we can modify it so we'll handle that case so here we'll say guid dot triparts and we are parsing this ID and we'll say out guid and let's say note ID if this is true then that means the ID was correct then we can simply pass this note ID and if this is not the case we'll simply have an empty ID like this what is the issue here oh sorry we'll have it as string in a label string now this is fine so from URL everything is string so it is easy to get it as a string then we are passing it here so we'll get use this node ID to use the actual guid node ID now we can have one more uh computed property that will say is new node right and here we can simply access the node ID or we can access this ID so we'll say if ID is null ID is null or if additional then it is new node because we did not get any ID or we can change this to have the if string Dot is null or white space ID then this or if that is not the case then we'll save note ID is equals 0 ID dot empty empty so this will handle this case so if there were some invalid characters invalid uh invalid characters in the ID then this node ID it will have guid.mt so we'll have this empty and when it is empty then we know that this is not the correct note ID so we will consider it as a new node basically we are creating a new node okay now if we have this note ID then we need to populate the data the existing data so for that we will override on initialized racing like this and here we will check what we'll check we'll check if this is not the new node if this is new node we don't have to do anything because the new note case was working fine we are making these changes for the edit node functionality basically so if this is not a new node now we will fetch the node here so for that we need to have some uh some loading logic basically so we already have this underscore busy but we will not use we'll use let's say aged patching this flag we will set this cage fetching to True here true after this we'll say we'll set this model by using the nodes service dot get node async and we can pass node ID to this when we created this we can pass guid ID which in our case is node ID what is the issue okay it can be in a label so we can first take our node equals this okay and then we'll check if note is not null or let's say if notice null so somehow we the user entered uh invalid not invalid a valid guid but this does not exist in our storage basically so here what we'll do we'll simply show an alert alert and we'll say palette service dot alert async message so we'll say invalid or we'll say node does not exist node does not exist and the title will say not formed something like this and after this we can okay we can modify this by having a next line and we'll say we will for let's say this form will be used to create a new node something like this or maybe okay let's do one thing let's not do anything node does not exist and from here we will simply use navigation manager navigation manager dot navigate to after this we'll navigate user to the previous URL and in this case we will use the other parameter that is this Bool replace because we don't want user to come back to this previous page which has a guid which does not exist in our case right so we can use this so we will use would replace true like this and then we will simply add this return statement so that further code or does not gets executed if this was not the case if we were able to get the note then we will simply set our model to this node and after doing this we can set this is fetching to bonds cool now we need to use this is fetching flag for that let's come here and after header after header where is the header header is here right after header we will not display any part we'll simply have this check here if is patching is true we will show our loading component right and the loading text should be patching node and if that's not the case then we will display the actual form like this tool so it should work now continue editing one thing will change the save node we will modify this title as per our case so if we are creating a new node new node we'll say add a note and if we are editing it we'll say edit node so instead of this hard-coded save node we'll check is new node if it is a new note we'll say add a note is already there and then we'll say if this is not the case we'll say edit node we'll save it and stop and rerun [Music] let's see how it looks it is coming okay we can see everything we can click on it and we can see add a note which is correct go back this is edit and we can still see that a node because we need to modify the link of this add description right right now we on the home page we have hard coded it this add a description link this one we added it hard coded right so we need to have after slash we need to have the note ID then this nav link component these components the Blazer component basically we cannot have the computation in the attributes of Blazer component so we can either have all static thing all static text like this save or slash One Two Three or something like this or we can have it totally Dynamic but we cannot mix and match what I mean is we will have added link here we'll say edit link equals and we need to have this as the save is hard coded part then this is dynamic part which is node.id so we cannot mix and match these two things so here now we can use this like add date link like this and now we should be good save everything and let's see if it works yes you saw that go back come here and we can see the edit node and node title got uh fast so we can see it and we can see the that loading indicator as well by introducing manual delay basically so here we can say await task dot delay let's say two seconds save go there and we can see patching node and then it got the value and it changed this title the snap bar and then it got that title as well now we can remove this save and we can cancel it and we can update it so nice thing is we need to work on update case so when this is in edit mode we have only one method which is save node async where we were always creating a new node but that is not the case now right we have two conditions so here now we'll have our condition so after this setting these two busy equals true will check if this is a new node then do this if this is not a new node we will simply say a weight node service dot update node async and will pass the same order like this and in either case we'll simply redirect user back to the home page that is we are going to do for sure in both the cases save everything and now let's see if some things got updated on so this one the last one you see this is the modified time is 127 we'll add a description we'll modify this so we'll say modified Titan we will save it and now we should see modified title time is also updated right we did not update the description because we wanted to come back to this page modify title let's fix this spelling and now let's add a description as well description as well save and now we will not see the add description because now this note had description right cool so this thing is also working fine next thing now we'll work on these two buttons right this will change the layout so right now it has this grid layout by default but we'll make it dynamic so for this we need to let's go to home page first we need to have some state so that we can check that which layout we are currently using so for that what we'll do we'll simply have one private variable here we'll save Private a string let's say main column class so we'll say main call class and the default we are going to use call 6. so because bootstrap uses 12 column grid so call 6 means half of the screen that means we can show two columns so this grid is the default layout and now we'll use this main call 6. to uh we'll basically toggle this how we are going to toggle this first we are using this call 6 here so we can modify this like this main call class and the same thing we'll do here we can do this Dynamic and static both because this div is not double as the component this is simple HTML so we can add simple we can add Dynamic and static things we can mix and match on HTML attributes fine so right now if we save it nothing will change only the Blazer hot will reload will not work that's the only change okay do let me know in the comment if for you all these changes Works without restarting the app or you also face this problem this short-term mobilizer hybrid hot reload just uh freaks out it is not related to daughter Maui actually it is related to Blazer to work on toggling these two things so this section is here right so here uh we have to approach either we can have this inline here or we can have a method and from that method we can use this okay so let's do this let's have a toggle method so here after this one initialized we'll have one method where we'll say private void toggle layout okay and here what we'll do we'll say if main call class if this is pole 6 we will set this mean class to call 12. the complete width and if that's not the case we will simply set this to call 6. 6 like this toggle layout fine now let's use this toggle layout for both of these buttons so we have this button here so here on click we'll call this method and same goes with this second one this one save everything let's try if it is working and now it is different it should not work like this right if we first click on some other then it will not work so this is not correct we should pass the current layout right so we'll modify this method a bit so what we'll do we'll pass the current button which we are pressing which right now we are pressing the grid that means call 6 so six this is the button we are pressing right now like this let's copy the same thing and add here and this time we wanted to call 12. we'll come here we'll accept uh uh let's call it CLS or button class BTN Plus something like this string and now we'll check if main class 8th main call class is already BTN class then we'll do nothing or let's do the opposite if this is not this B10 class already then we'll simply set it main plot plus equals this B10 plus like this we can get rid of this now fine save everything rebuild and apply changes loading and now we can see we are on here so it will do nothing if we go there then we can see this bigger layout like this now this thing is working right as expected we can toggle the layout the only thing is we should show some visual indicator which shows that the currently selected layout is this one okay so for that our BX classes this box icon provides we can actually modify the color of this by using the styles box icons uses the style inline styles to do this so here we can check if this collects so we'll have some condition here we'll check if main call class if this is called 6. that means the current class if this is the case we will set the color to the main color the selected color so here we'll say we have a color as where color Main uh like this and if this is not the case we'll have an else condition and in else we'll say color let's give it like this oh it should have been question mark yeah like this and if that's not the case we'll set color to Green save it and we can see this dark color like this and we'll do the same thing with opposite classes in the next thing so let's copy this style and add this on this second one the only thing will change we'll change it to call 12. save everything now we should see this so this is disabled this is like this now if we change it now we can see this this is the selected one and this is grade that means the light faded color so this is also working cool now next thing is let's work on these two pages for Blazer web assembly then we'll come back to work on these actions the edit and delete node then we'll come back to this okay so let me stop this right now and let me run the web assembly version to run it now if you remember I showed you the layout so now we should have something which will tell us that the current environment we are running on this is uh dot net Maui mobile app or Blazer webassembly browser right so we need that for example in the save nodes uh page for for both the pages we had this Maui navbar this section so this makes sense only for mobile app right so it should be rendered only for mobile not for Blazer web assembly the browser version so we should have something so for that what we can do we have these services like this I alert service and all those services so we can have one more service in interfaces we will create one more interface and we'll call it let's say public interface and we'll say I platform let's call it type platform only and here we can have a property which will be of type Bool and we'll say is browser browser it will be of type get only like or we can have some other things as well so let's rename it to I platform service and we can use this browser let's move it to its separate file I platform service and we can have its implementation in both the projects VR services will create a new file here uh in the dot net Maui we create it we'll call it platform service add real change internal to public and then we'll Implement type platform service platforms service this one we will implement it Implement interface and here we know for real and this this as plots save find and we'll copy this thing we'll go to webassembly version dot web project here we have Services here also we'll create the same class file let's move it platform service we have this platform service and here we know this is Blazer webassembly browser version so we can pass them from here this hard-coded and now we can inject this I platform service anywhere in our entire app and we can use this so we'll start using this on home page but before that let's see how it looks actually on the browser side how it looks there is some error and if we check it which is the error console um home page there is no registered service for notes service fine we have not registered node service and now I remember we have not registered platform Service as well because these things are in we have registered these in Maui project only let me go to my program and we should register platform Service as well so add Singleton right platform service platform service platform service like this and let me copy this entire thing and we'll paste it in our webassembly version as well program.cs and we'll do this pave everything and same thing we'll add the Imports as well so we can have these common let's go to this one and it's common like this saved everything is saved let's run it it is loading and we can see all nodes so we can see this plus add a note right but this is not we what we want for browsers first thing we need to have a complete uh a different background basically but before that let's try to click on this add a note and if you go there we can see this design which we don't want on this page we need a different uh UI for browser version basically why we can't have that why we are not having that header so we are having that header but because now we never this CSS does not exist here that's why it is not having this we only have this text right and if we remove this we can see this welcome away Prince and then there should be somewhere that bless icon we can see that from here if we remove this text point we should see this thing so this is like this but this is what we want what we want so let's stop it first let's come on the home page we will inject our I platform service we need IE platform service and let's call it platform only platform and here first thing we will check the platform is not browser it platform is not browser then only display this header same thing will go for this save notes page here also we'll inject this and this header this now we never this section we will have this only if the platform is not browser we will say if this is not browser then only do this the thing so it should work now we had that background in common only right on body we have this background color then why it oh it was not coming on this web assembly version because we have not added this CSS so on web triple W root we have this index.html and we have not added that style here so we should add the style here so we'll copy the same style we are having in dotted movie HTML and we have this box icons and this common.ca systems board copy and let's paste this here save everything and run it this time we should see the background color and this header should not be here okay still not see this yeah sometimes it simply have those static files uh in Cache because so we can simply enforce it we can uh use Ctrl F5 hard refresh so that it comes fine now we have this background color we have this all nodes and what is this for this layout so this layout section also we are not going to have it on browser version we need to have it only on mobile version because on browser we have enough space already so let's add the conditions for these as well on home page we will check thank you so we have these filter buttons here right so this section we can inside this only let's do this we'll cut this we'll have if condition here if uh platform dot is browser if this is not browser then only we'll display these and if this is browser so let's do one thing we can have okay let's skip this for now we are good if this is not browser then we'll add these two buttons If this is browser then we can simply have one H5 here and we'll say welcome and we'll display the username here in this case because in mobile version we are displaying the username in the nav bar but on browser we are not displaying this so there is no username so we will have that username here and on this we will have text white because we need to have it in white color and same should go for this because it's all nodes also this is in uh the default dark color we should the background is this so this all node this should be in white color so we'll add text white class on this all nodes but that should get supplied only if we are on browser here we'll say if the platform dot is browser then add the class text white if that's not the case do nothing save everything return and now we should see the browser specific header on left all nodes on right welcome username and both of these should be in white color Trace loading all nodes and welcome away Prince so we can see this now find we have add a note we can click on this now we have this save uh this sale page on this also what we need on this browser we are going to have one card which should be in the center of the screen so we will not use this layout we will have that card in the center of the screen so let's do this will stop it so we should not have stopped it but okay that's fine now on the save if this is not browser we are ending this platform and all this now if we come in this container fluid here we'll check where we can have that logic that card when we have this mobile form container this mb3 this section [Music] so these two things we are going to have the same thing but we will have a uh if class Dave class card here and in the card we should have the flash card header and pin header will show that if this is creating a note or editing a node section so this H5 we will have it in here and then this section these two should have in card body like this and then these buttons this should be in card footer now the problem here is we need to display this card header card card filter all these only if we are on browser if we started to add conditions here there will be so many conditions right again and again we'll have a condition here if this is browser then render this if the this is browser then render this div and then this div is going to be the incomplete tags because this requires ending tag and that comes here on line number 74. so the dynamic markup that is going to freak out so instead of having these many conditions what we can do we can create a component and we'll use that component here and how we are going to do this on this components folder we'll create a new component let's save it save no inner component something like this and we will inject inject our platform service here I platform service we'll call it platform and here we are going to have the condition here we'll check if the platform platform dot is browser platform let me change this to lowercase L if this is browser do something if this is not browser then do something else so in case of browser we'll have those team Plus card God like this save inside this card we'll have our card header Dave class card header or then we'll have body then we'll have footer card header card body and then card footer and when it is mobile version we will simply have a simple div uh if we want to have some class we can but we are not going to add any uh styling to this so we should be good but let's I have this something like say mobile save note from uh card something like this okay now in card header we need to use this same thing this line now it needs is new note so we cannot have it on this page so we'll accept this as a parameter so we'll say public pool is new note and we'll send parameter we can access this now fine after that we need to have this card body and card food then this card body this section we are going to have let me first remove this card card header from here cut putter and then this card filter right now these two things title and the the stacks area these two things we need these in here we need to render those here but the point here is we need to render the same thing in this card body and inside this one line number two zero twenty so for that what we can do so what we can do we can accept this section also from the consumer and in this case consumer is the save note page right so we can accept these as a parameter for this component and the HTML we can get using the default render fragment thing so in render fragment Blazer I have one child content this is the default render fragment we can use this and here we will say this should also come as a parameter and then we can simply render this in both of these spaces right then comes this footer so footer also is going to be dynamic right we need to have it we will need this for both these cases yeah we need this for both of these cases but for now let's have it set this only this also will accept as a parameter what we'll do we'll do the same thing in order to accept HTML we need to use render fragment and this child content is default and we can add our own as well so in this case we'll say footer content now we are okay to use this component in this page first let me paint this as well plan now what we'll do in here inside this call xxl5 and all this basically we will use our component and the way we are going to use it we will directly use Save node inner it expects one direct parameter which is is new node and for this we already have this new node we can pass this then comes the part if we had only single random fragment without this thing then what we could have done we could have directly added this HTML there is complete HTML here so it should have been worked but now we have two random fragments if we have more than one render fragment then we should explicitly tell a Blazer that this particular HTML belongs to which kind of fragment so in this case first We'll add child content and in child content we are going to use these two things so we'll add these like this so now we have title and description fields in this child content and that after that comes the footer content and in footer content we are going to have our button okay so the way we need to have our buttons pour this okay okay this thing on a browser we have that in footer we had two buttons cancel button on the left hand side and the the save button on the right hand side so we need to have two different footer contents right so instead of this okay not okay we'll pass the conditional [Music] order content from here so we'll say if the this is not platform dot browser that means this is mobile so we'll simply show this only okay and if this is not the case and if this is not the case for browser we'll add a different marker and now we can get rid of this mobile phone container we are having this inside this save node enough fine so let's do this for this footer we already have this footer thing so here we'll have two buttons first we will have a cancel button so that is going to be enabling because on clicking on that button we will redirect user to the previous page which is the home page so here we'll have slash home and then we can have a couple of classes BTN ptn BTN D power vtn default PT and SM foreign then the second button which is going to be actual submit button we will say button type type equals submit submit and then we'll add classes we'll say save and the classes we are going to have BTN BTN success and BTN SM cool so we have this footer content also okay let's use this busy as well so this busy thing let me copy these two lines here we'll have if is busy if it was trying to notice busy it is busy if this is trying to save the node right now and in this case it is not saving so if it is not saving we'll have these things if it is saving then what we'll do we'll simply disable these we will say disabled let's add the disabled class as well disabled on we'll change the submit button to button and add the disabled attribute to this cell will disabled and we'll change this save to this saving save saving so is busy is fine this is fine now we are not using this footer content on this page so let's render this portal content as well so for browser we will render this inside card putter and for mobile.net we will render it directly after the child content like this cool so everything looks fine now let's try to run it for the Blazer web assembly first then we'll check it on the Maui if something has changed or everything is same okay this is here let's click on ADD new note and we can see something right add a note this is card cancel save note description everything looks similar we'll design it further for the uh for browser but first let's see everything is coming here now let's try it on Maui side if everything is still same on the mouse side as well run it run Mouse loading and let's go to this page and here you can see everything is same validation is working everything is working fine we can have the header we can have these things we can have this button so header footer content everything is working fine cool so next thing we'll work on designing this form this save nodes or are blizzard webassembly browser version right now I'm going to take a break and I'll pause the recording and then I'll resume it after five to ten minutes okay till the time do let me know in the comment if you are still following and press the like button if you are liking this series this video okay I'll be back soon so what we'll do here now let me first run it then we can um let me navigate to this page fine now first thing we need to have this in the center of the screen this add the note section uh this card basically and we need this only for browser so what we'll do here this is the main container this div class and this call all these classes so what we'll do here we will have one conditional check here and there will say if platform dot is browser if the platform is browser then we are going to apply two classes MX Auto that means uh Auto margin for x axis from left and right and same 4 m y naught two so that it moves to the center of the screen then this empty three class margin top 3 we don't need this for browser we need this only for mobile.net so we'll add this else condition here and we'll add this mt3 to this case mt3 like this so now all these classes are common then MX Auto my auto this is only for browser and mt3 is only four dotted movie so let me save this let's try to restart app is loading and if we go to the save page we can see this is in the center of the screen right now fine next thing what we need uh this background color we need a different background color for this browser version so let's do this for this right now the background color we are handling it using this BG main lighter this color and this for both these cases but now we need to have a dynamic check basically because this fraction is common between these two modes but we need this Dynamic and this input text is a laser laser component so we cannot have that condition directly here we cannot have like this we are checking it here so that we can't do before this what we will do we will extract out all these classes in a variable so here we can say Y and let's say Ctrl BG color okay and here we'll check or not basic yeah we should have control BG color and for this we'll check if platform is browser then we'll use BG light and if the platform is mobile then we'll use what we were using the BG main lighter this PC light is coming from bootstrap and this we created then we'll say control uh class list something like this and here we'll add all these classes like this we have different classes for these two right here okay so it makes sense it will make sense if you create two variables here so first we'll say title Plus title class list and here we'll add all the classes we are using in title we'll cut it we'll paste it we'll remove this busy main color and we'll make it dynamic using this control basic column and then we can use this thing directly in this class same thing we'll do for description let's add this instead of title this time we'll say description and let's see the classes we are using on description field these are these glasses cut description class list and then we can change the description class list and we can remove this BG main light fine so we are good with these classes then one more thing this style mean height so this is for mobile but on browser we already have a very let's say bigger space so we will show displayed smaller on the browser so for that also this is inside this input text area Blazer component we cannot have that condition here so we'll extract this out in a variable again so what we'll do here we'll say one description Style and here we'll add the check platform dot is browser if this is browser then we'll say Min height uh let's say 150 PX and if it's browse uh dotted mobile then we already have that height that is 250 PX like this then we can use this description style here um fine so we are good with all these changes one thing you can do for a better uh maybe better standards so we are having these four lines and we are checking this platform is browser again and again so instead what we could do we could have all these in variables and we can have the single check for platform browser in the on initialized async then we can set all those variables here and we can directly use those variables so this check would be only once but I'm adding it here only so it's up to you this is not going to make much difference but these are two different approaches you could take okay so let's re-run it we will see how it is looking now Okay add a note and we can see this like this add a note the color is different and now this section let's work on this section as well cancel save buttons in the footer so all these Footers we are handling these in save note inner this footer content and if it is not browser then this is browser so this is the case here we just have two items in both the cases let's go to Inner we have this card photon on this card footer we could add classes we'll change this to display Flex and we'll say justify justify content between and if we save it and if we check it now we can see this uh on the corners right cancel would work as before and the save we can see the data annotation validation error and yeah we need to fix this red color as well so we fixed it for Maui we'll do the same thing for our Blazer web assembly as well so if this change was in CSS so we'll modify the CSS for that we'll go to our Blazer web assembly ww root CSS app.css and here we had these outlines for invalid and valid so we'll do the same thing we did in Dot and Maui so we'll change the this with that the Border color with the same color we are using here so it will blend in in the in the Styles if we are having borders then it will simply use this border color if we do not have borders for example in our case we use border zero we are not using border so it will simply skip this right save everything fine we are here after this that save button this looks a bit different and that is because let's add node BT and it should be BTN only BTN BTN save and now it looks nice okay let's see add a note what if we added some incorrect string incorrect guid okay it will not allow us to navigate there and that is because uh we have the check in our app.reason which checks if we are already if we have the username or no if we already have the username we always redirect user to the slash home page so I think that is fine okay now let's try to add some note first note from webassembly browser and we will not add description here so this got saved and we can see this add description button which we need and then these three three dots but these three dots we added these only for mobile version the.net Maui version because we had a very small space but on browser we have enough space so instead of showing these three dots we will display the buttons here edit and delete button basically directly so let's go to home page for this and here we have this action section so in this actions section these two buttons sorry after this uh modified on date and this day basically we are going to modify this demo so this is the that vertical menu so we will have this only if we are on Dot and Maui side here we'll have a condition if platform dot is browser else this is the mobile version we are having it like this and if this is browser then we'll simply add two buttons here to button type button and it will be added but first we'll have delete button then we'll have edit button so for delete button let's add classes plus BTN BTN access BTN like this and then BTN danger so that it uh shows in the red color okay and then we'll display a icon from box icons so the icon is going to be BX box icon BX trash like this and then we'll simply copied or no not from page we'll use nav link for the edit button nav link and for this will navigate user to the edit page with this node so we cannot have this Dynamic ID here so we need to have that as a variable which we already have I guess where was it this edit link let's let's extract this out directly in the forage here so that we can use it at both the places we are already using it for add description button now we'll use the same thing here edit link and for this we'll use a bootstrap box cycle class which is going to be BX BX edit and then on this nav link as well we'll add bootstrap classes so we'll say BTN BTN primary BTN access let's save everything and let's see how is it looking okay it looks fine but we can remove access and we can change it to SM save and it looks nice right we can click on edit and we will be redirected to edit page and we can see the name of the this card header this this is changed we can see the URL now has this ID and when we click on cancel it is going back to this page which is fine and same thing should happen when we click on this add description when we click on it it should open this edit form cancel and if you click on add note then it will simply navigate with add a note so this is a new node functionality let's try to edit this let's say add a description save and now we can see I have added description I can see the description that we saving was done and now we don't have that add description button because we already have description right cool so it looks fine both of this page looks fine now let's see if all these changes are okay with mobile version as well.net my version so that we'll see if everything still same or if something changed everything should be same if something has changed we'll fix that okay app is loaded we can see the home page same we can change the layout right we can click on edit add description it is navigating to the edit node we can close we are coming back add a note it is also working validation is working close let's try to edit okay we don't have edit functionality here but we can edit this one and description edit description save it loader and it got saved moved back and now we can see this description so that means everything is working same as before so nothing has changed and now we have working on both the platforms cool okay so now next thing we are almost there at the final stage we have I think couple of functionalities remaining very small functionality first one edit and delete functionality so editing one mobile version basically the dot net version so we have this dots this button so when we are clicking on this we should open uh device platform specific that action she basically photo select one of the available options and the options we'll have same as we have on browser we have edit and delete so we'll have both of these options here now we have a situation we need to have this somewhere right now this page is going to be sorry going to be rendered for both webassembly and Dot net Maui so we cannot have it here I mean we can if we want but that is not the right approach apart from this we can have uh different implementations or we can simply go to this I platform service and we can have that method here but the problem will have we need to have the implementation in both the classes 4.net my platform service and Blazer webassembly platform service but the problem is this functionality does not exist in browser webassembly in our case so what we will do here we will simply create an interface or we can have the default crew not implemented exception from the Blazer web assembly side or we can use C Sharps optional uh what it calls optional interface body Dynamic remember what is the actual name I have never used it but I am going to use it this time so what we can have we can have here tires string and here we'll say uh two from multiple options something like this choose from options like this and here first we'll have a title and then we'll have a variable number of options so here we can see we can have like this but this time we'll have a default implementation and from here what we can do was it like this only we will say rectangle we know this is null okay so it is giving this we can say Written Task without from result and then we can send them like this it does not work okay return null let's do this we don't waste we are not going to waste time on this we are good with this so we'll provide but this is just for the sake of Laser Web assembly we are not going to have this option there that's why I am having it here then what we can do we'll implement this method in our dotnet Maui side we have this project we have Services we have platform service and here we can implement this method like this like this and from here what we can do we have page no okay what we'll do we need to have access to page so we can do something like this okay and we'll have this Constructor now we have this underscore page what we can have we can have paste dot display action sheet and in here we can have title and then our options but before that title cancel description description hotels we can have okay so the canceled will have cancel only cancel button then description this button we don't need and then we have this param string array buttons so we'll have these options here and it Returns the value of the selected option so first it needs to be awaited and then we'll simply return it and because this is a single line we can use the Expression bounded method will do like this fine so we are good with this and now we can use this tools from options in our page so this home page will have a method here private is sync task and let's say node actions or show note action something like this like this sorry and here we will expect note ID and here to be double Shear we will check if this is platform dot is browser if this is not browser then only we'll execute this logic and the logic is going to be we'll simply display the options and options we are going to have first we will simply our result equals or we can save our action equals a weight platform service platform service Dot choose from options like this now we can use our method those options first is the title we will say node actions actions and then the options and options are going to be this delete note and edit node now we are going to use these when we are checking the this actions value so it's better to have these as variables we can have this constant server const string or let's say it in me node delete node and we'll simply copy it one more time we will rename it to edit node and here we'll say edit node and then we can use these constants when we are adding these options so delete node and edit node like this fine now this action is going to be either null or one of these two options so we'll check if action is not null if this is null we don't have to do anything this means user pressed the cancel and then that the display action sheet that pop up for these options it simply got removed from the uin we don't have to do anything in this case right if that's not the case we can have switch case or if else condition for now let me have switch case so here we'll check first case which is going to be delete note delete note if this is this delete node can we have like this control cannot fall out of switch can okay break then we'll have second case to edit node and break like this tool and there is no other case so we don't have to use the default case now for edit case we know what we need to do we simply need to navigate user to the edit page we will say navigation manager so I think we don't have navigation manager injected on this page so let's inject it inject navigation manager navigation manager so I'll have the systems services at the top then our custom services after this okay we have navigation manager now navigation manager dot navigate to and now we can have save and then this node ID which we have in this ID and after this we can simply return from data so we are good with this added node now to delete note we are going to have this delete node functionality for both right so because we need to delete node on from.net Mouse side and from browser Blazer web assembly side so it's better to have a common method here where with the private async task and we'll say delete note async and here we will simply have the node ID like this and from this delete node we can simply call this a weight delete note async and we can pass this ID tool we are good with this now let's add the show note actions link to the menu where we need this so we need this in this button when this is dotted Mouse when this is not browser we'll create our own click and we'll use this syntax we'll call this and we'll pass the note idling which we can get inside node.id fine so we have this thing we'll save everything now when we are deleting our node we should have one confirmation uh prompt confirmation box right that if we are real if we really want to delete this so for that we have two different environments we have browser with Laser Web assembly and then we have dotted my mobile so we need to have a platform specific confirmation box so that means and this belongs to alert service so we'll go to I alert service and here we'll add one more method which will return Boolean and we'll call it confirmation confirm async here we'll have a message we'll have a title with the default confirm and then we'll have button names and now uh the confirm box we are going to use JavaScript confirm box for browser and there we cannot set the names but we'll use default OK cancel buttons but we can have these optional button names which we can use in our mobile version the.net Maui version okay so here we'll say the string OK button which will be so now let's have okay only and then we will have a cancel button a string cancel button and it will be cancel default value save everything now we need to provide implementation for this confirmation for both the alert Services first let's do in dot at Maori side so we will Implement interface we have this confirmation it needs to be async and now here what we can do we can have a paid page dot so confirm we don't have direct confirm but we can use display alert with some additional parameters so first we need to have title so what will you use we will use this one which has title message accept and cancel and it returns a Boolean we'll use this one so display alert first we need to have title we'll add title second message we'll have message then accept button this is ok button basically so okay button and then cancel which is cancel button and then we can return it directly like this save everything we are good with this one okay we'll come here and now here we'll check if alert service Dot confirmation and here we'll ask the user if he really wants to delete this node so message will say do you really want to delete this node like this and then the title will fade confirm delete like this and we need to await it and now we have this if condition so if user pressed yes on the dotted Mouse side and OK on the browser side then it will come inside this and from here we can delete them how we can do this we have our node service and there we have a delete noticing method and where we can pass our node ID like this and it will work but when we are deleting we should display the loading indicator that something is happening for that we have so we have something here is fetching so is fetching does not make sense now the name does not make sense will change this each patching so let's say is loading something like this and then we'll use this is loading two true is loading true and after doing this we'll set its loading to false and we should have these this line in try finally at least or we can use this try and try and catch try catch exception and finally we'll set is loading to false and in this exception we can simply display the added like this and here we'll see error in deleting deleting no like this fine now there is one thing now if we check this is loading so we are using this here and now when this is loading is true it will display this message patching nodes first in this case this is not correct right so we should have stayed for this as well which we can modify so what we'll do here when we say is loading is not making sense it should have something is processing or is busy let's use this is busy what is the issue okay let me manually change it [Music] okay something is not right so I'll manually change this to paste PC Fiverr currencies then I'll have one more piece of state which is going to be string and here we will say busy text and where we can say patching nodes this we can have default value if we want so then when we are doing this hbg equals true we'll set this busy text to deleting note like this and then we can use this busy text variable to pass today's loading component this one instead of this we'll say at the rate underscore VG text fine okay and when the deleting is done when we are resetting this is busy at the same time we'll reset this as well let's say to blank string now after deleting the note we need to remove this node from this current screen so [Music] now let's do this we will simply reload this complete nodes for that what we can do we can extract out this logic from this on initialized async we can create a new method private is sync task and we'll say load nodes facing async like this and then from only initialized async we can directly call this method a weight load node sizing and same thing we can do from here like this a weight load note is sync and but before doing this we will change the busy text to patching node like this patching nodes Cooling okay everything looks fine sometimes when we are modifying these states uh one by one sometimes the State change detection does not trigger in that case we can explicitly use instead has changed so that it triggers the change detection and it re-renders this component with this new value we can do this as well cool everything looks fine now let's give it a try on mobile side foreign press this we can see the note exchange and we have a typo let's first check the functionality then we'll fix the typos so we can click and it opens its not actions edit node delete node let's try canceling it is working let's try at it it went to the edit screen and we pre-filled these data cancel and let's try delete node we have this confirmed delete do you really want to delete this node no it the pop-up cancel basically without doing anything and let's edit this note and we'll say we are going to delete this save we are going to delete this node this one let's add it sorry press on Note actions delete node and yes this time it got deleted and there was that fluctuation which was showing that louder and now this note is not on the screen so that means the complete functionality from these Dot and mouse at working we just need to fix this typos note actions and let's remove this redundant note word from the options we will have select simple delete and and let's try note actions delete and edit looks nice cool now let's go to the webassembly browser side and from there first we need to have this confirm this confirm async method so now we are in web assembly services alert service will implement the confirm async method here change it to the sync then instead of through let's use the similar approach we took for this prompt only the thing will change this window.promptu window.com we have this native JavaScript confirm dialog box and it will return a Boolean and we are good with this we are using title and message we cannot pass the button tag for this and if you really want to uh use this okay and cancel button then this native JavaScript box is not going to work you can Implement your own confirm box and then you can pass these buttons and customize these buttons save everything we have this alert Service confirmation fine let's go to home page and we'll use this delete note async from the browsers webassembly side we have this else and we have this platform dot is browser edit is already working for this delete we can bind our method so on click like this we can call our method which is the delete node async and we can pass the ID of node dot ID let's try to run it webassembly okay we have this delete button if it's press delete do you really want to delete this node if we cancel nothing will happen and if we press ok then it got deleted fine so this functionality is also working save now next thing is we will work on that showing the note detail in the pop-up if you remember the final build version I showed you there we can have this let me add some random first save everything and when we click on this this description or this main node text it should open up a pop-up where we can see the details and we can copy the new text and note title and description basically we can copy this so for that what we are going to do we will create a new component so in the common components project in components folder we'll create a new component eraser component and we'll call it let's say view node details like this so we'll have this let me delete this first so we'll use builds as the model pop-up basically protein class and then we'll add some classes here first we'll use position fix position fixed this is coming from bootstrap then we'll have and display let's we can have or let's see without this it works then we need to have it cover the entire screen so Left Right top bottom all zero so for that we can have a style tag here Style type text CSS CSS and let's say let's call it full screen and here we'll say left 0 to write 0 .0 bottom zero and important and this position fix let's have it here only position page like this then we can use this full screen directly here like this Polo now after this full screen we'll have one overlay this is the kind of uh our pop-up models container wrapper then we'll have one overlay so that we can show some faded background for that we'll have a depth here let's say overlay and this name is very common it could overlap with some other uh CSS so let's have it an overlay notes overlay something like this and then with this fan overlay we'll use the same full screen class as well and then with this n overlay what we'll do here and overlay will have background color or maybe that we can directly use here only BG main we have that background color right and it instead of background color in on and overlay we'll use opacity 0.5 like this now after this we will not have anything inside this fine now we'll have our actual uh content the actual HTML which will display this the complete thing so here we'll have one more div and in this div first let's move it to the center of the screen so we can have MX Auto and why Auto it will be moved to the center of the screen and we'll have our box class as well it's full screen let me move this full screen to our common CSS CSS common hair because this is very common this can be used at other places like this save and then n overlay this is related to this component this thing only so we can have this here 0.5 but and in this big class order now we can have first we'll have a button to close this modal pop-up we will have a button class vtn vtn access will have its small vtn BTN access PT and benzer red color and then we'll have this cross sign periods is X or we have I class BX PX what was its name save note page we have the this one b x x like this okay we have this button to close it after this we'll display a p and in this P we will display node title but we need loot to display this so we'll accept this as a parameter we'll say public note and node and this is going to be in parameter parameter and then we can use this node to display it here we'll say note dot title and we'll add a class here we'll change the font size fs5 save after this now we have cases our description is not required always so we can have this without description so we need to handle both the cases we'll check if string dot additional or white space note dot description if we don't have if we don't have node we should we do something if we have node then we'll display that node so let me copy the same pin and we'll display the description here and we'll make it a bit smaller so we'll use Apache 6 here after this we'll have online HR and after that we can display those options remember to copy and share the node so here we'll have a Dave class we'll add some classes then we'll have a button first button type button class BTN vtn SM and we'll use this flip Flags Flex column like this and in this first we'll have I class that copy icon basically so BX BX copy we have this and then bxsm and after that we can have a span and where we'll show the copy text cool and we can copy this button paste it again 4r uh share button so the class is going to be BX share and this text is going to be shared now this share button we are going to use native share API from.net Maui so we are going to have the share button only with dotted movie version not with the browser version so we need to render it conditionally for that we can inject our platform service High platform service let's call it platform only platform and then we'll check here if platform dot is browser if this is not browser then we'll display this share button else we will now display this tools looks fine we'll see if we need to add a couple of okay these two buttons we should have the cell display Flags and justify content will use around here so space around so these will have even space between them and the corners save everything now we can use this uh this component on our home page right but we cannot always render it right we should render this component only when we have clicked on title or description because then only we want to show it so we need to have some flag and then we need to keep track of which node we have played before that what we can have we can have a private variable here which will have the label node and we'll say viewing node something like this the default value is going to have been null because we are not viewing any node and then we'll say will modify its value when we'll click on description or title in this case let me have a method here we'll say private employed and we'll save view note and we'll have a node complete node details go like this so from here we can set view node equals node like this okay and we'll call this view note method from uh where is our Title Here is our title from here we can call it so we'll say on click and we'll save view node and we'll pass our complete route from here and same would go from the description when we have description on this p then we will do this okay now we clicked on the title or description it got executed we set viewing node to node and when this happens we should render that view note component when the viewing node is not null like this here we'll say view note it ends right and on this component I'll add editor required and that is for let's say right now in order to work this component to work we need this node so this node is required right without this there is no point of this field and if we come here I have not provided any value and it is still not complaining about anything so we might miss this thing so Blazer tooling it gives us one attribute which is editor required put it does it simply you see this line if we hover over it it says component view node model expects a value for the parameter node so it is telling us that we you missed this will provide this value in this case this note is going to be this viewing group so if we save everything it should work but the only issue is we will not be able to come out of this model because we have not implemented that functionality that we can close that button and it should gets removed from the UI we need to implement this first let's see how it looks we are on browser webassembly if we press it we can see this thing and nothing is happening so first we'll design this thing and on the screen this thing then we have MS Auto and why hmm and also new screen [Music] will have display flags on this full screen a plants like this after this for this button we need to have it at the right side so what we can do for this button to this place we can say a line self and line cell and like this okay and this button okay looks fine so let's add these two things on full screen so these are view node model this one on full screen so we'll have the flags and on this button we will have it was complaining about this button type button and here we'll have a line cell and save everything Pine we can see copy let me find now when we press this close button it should close this pop-up right and how this pop-up is going to be removed from the UI that we are handling from its parent which is this home page and we should set this underscore green node to null in order to remove this from the UI and this underscore view node is on parent components and we are on this child component we have this x button on the child component so we need a mechanism a process by which we can call something from the parent component for that pleaser gives us the events basically event callbacks so in this component we are going to have one more parameter which is going to be of event callback we don't need to pass anything we'll name it let's say on close and it should be decorated with parameters so it is on close when we click on this button we can call this one close we can directly have this on click on close run save and on home page now we can use this on close event and then we can do our the thing is going to be we can set this under so we should set this underscore view node to null here so let's use this view note method only and we'll make in the label and then we can directly call it like this we will say view note null we are not viewing in any node save everything let's see if it works close okay let me restart this and like this it is coming okay win node and we can close it when node we can close it so this is working next we'll check it on the mobile dotted mobile side how it is looking foreign run let's see this it is loading okay and if you press this we can see this problem okay and we can see both of these buttons copy and share we can have some minimum width something like this on this this section no not this this one on this full screen reflex and overlay here we'll say let's say and model and here we'll say main width it should be something like um let's use it and modal class on this main container like this no no not on this one we should have this on the actual container the container of this text on this AMEX Auto and why or two box here we'll have this chain model save everything and then we can see this it looks nice tool next thing we need to work on these two sections this copy and share first we'll work on copy because this copy is uh common between these two platforms so let me stop this minimize this and just copy and share both of these are platform specific we could create a new service or we can use this I platform service only so here we will say task and copy a sync copy async and here we'll have text then second thing for sharing so we can have task and Shear async then all in this also we can have this uh string text to share fine let's Implement these two first let's go to our browser so this web we have services okay here Services platform service and we'll Implement these copy and share for share we do not have this functionality on browser side so we'll have this only through new not implemented exception because if somehow we accidentally try to invoke this then it will simply through this exception so we can have this approach for copying we are going to use JavaScript for that we can inject the JavaScript so we'll say we'll have our Constructor will have IGS runtime JS runtime and this JavaScript gives us methods to work with the clipboard basically when we say copy this is copy to clipboard let me rename this copy to clipboard copy to lift board find save and we are here copy to clipboard here we'll say chairs runtime dot invoke void async because we are not going to get anything in return and the method JavaScript gives us that this Navigator dot clipboard dots right text so we can write any text to the clipboard and then second parameter is going to the text what text we want to write to the right text like this and it is going to be awaited so I wait and I think so we are good with this copy to clipboard and for sharing we don't need it so we are good find this browser side let's go to Maui side now we will go to our services platform service and we Implement these two methods copy to clipboard async and share using so for copy to clipboard we can have clipboard dot default Dot we have set text async we can use this like this outfit set text async like this we need to use a sync and we are good and for sharing we can simply say oh wait we have shared or default Dot request async and in this we can have multiple things but the over uh so we have implemented these methods as well it's always a better idea to handle exceptions here but I have not done this so now we are good to use these methods now we can use this let's go to our this one view note model and now this platform we should rename it to platform service because now this is a service which has some methods to now we'll have two methods here first we'll have private async task and let's say copy async copy each sync and then we'll have another one private facing task sharing like this okay and for sharing we can have an additional check where we'll say platform service dot is browser if it is not browser then only right now we have this functionality and from sharing what we'll do we'll say of weight platform service Dot share racing then the text and text we are going to have is first we'll have node title so we'll say no dot title after that we will have note dot description you know the dollar description we can have new line character here like this and we are good for copying it is available for both the values Avail platform service Dot copy to keyboard using here also we use the same that like this fine now just we need to just call these methods so this is copy we'll use on click copy async and for this one we'll say on Click Share essay share async save everything and let's ride first let's try it with dotted Maui then we'll check with browser okay app is coming we need to fix those loading and check authentication state that thing we should have some marginal bottom as well some padding bottom basically on this body right fine we will click on this we can see this copy and share so when we click on clear we can see the pairing and we can see the text right the title and description let me read uh edit this so that we can see the actual text so we'll say note title put title will say it's happening let me read in this okay edit here we'll say share this node and in description we are going to we will share this node using share button on both view node modal pop-up something like this save we can see this share this node and we can click on this we can click on the share and now we can see the share this note and this complete text cool next thing is copy we can copy this and when we copied this we don't know if we got this or no but we can try it like this in here can we paste it here no I don't know how can I show this but it got copied trust me okay now let's stop it and let's see this browser side so dot web and we'll see in browser webassembly British loading and copy and we can try to paste it here paste and you see this text is coming from there only it's better to create a new node with some same node text something like this we will copy that title title and description of this node using copy button save it property this move type and we can click on it and then copy it now let's see if it actually got copied we can share this now we can simply paste it and we can see this that this thing is working oh this looks fine the only thing is this UI these cards are very big so let's do one thing change the main layout class on this home page we have this container fluid this class will change this for browser here we can save platform dot is browser then we use container and if this is dotted Maui then we'll use container float the full screen save and let's say now it looks nice right we can say that we can I guess everything is working now right cancel add a note cool next we'll add that Floating Action button and after that we'll work on the that initial loading part okay so let me close this and let's add The Floating Action button that is going to be on this home page so on this we can have it anywhere we will use position picks so it does not make any difference but okay that is going to be a link to the save node page create note page so we can use it as an app link the HF will use slash save like this let's see this in action save and first let's see it in on mobile let me run it so that we can say it in real time okay we'll have one icon here span let's say plus we'll save it we should see somewhere here right now what we'll do we'll add couple of classes here class first we'll say text decoration none we don't need this underline so on mobile devices we have very small space so we'll have this plus sign only but for browser we can have enough space so there we are going to add one text as well so platform dot is browser if this is browser we'll add one more one text to it which we'll say add a note plus and then add a note save everything okay continue editing for now we'll add a class here let's call it Fab this is floating action button Fab next thing we'll add styling to this fan save everything rebuild and apply changes okay we can see this now we'll do the common CSS here we'll add styling for this first we'll position fix save then we'll have our left right thing let's move it to the bottom so we'll say bottom zero it should go to bottom it is here now let's have some margin let's say uh some ntx and then uh bigger font so we'll say font size yes and we'll have fun to wait and hold save it is here uh Bank of this card it should come over it so what we'll do here we'll have a chat index of three it is here now we need to move it to the center of the screen for that we can set left or right to 50 percent so let's start right 50 percent it is here or let's move it to the very right so we can have it zero right zero like this then we'll have background color here background color we'll use our main color we will use our variable colored main like this save next we'll have the text color which is color white save tool now we'll have some padding let's say 5px next we'll have a fixed height so we'll say height let's say 50. attached align Center within this save fine next thing we will have border radius 50 percent like this we have height 50 let's have width 50 as well 50 PX okay and then where we have font size we'll use LINE height line height let's try 30. uh okay fine this is in Center next we'll have some Shadow to it box shadow zero zero 30 pixel black like this cool now we can say something and it is looking great okay now we'll go to the browser the web assembly version there this looks fine on mobile and when we click on it it is navigating to the next page which is expected behavior let's stop it and change it to webassembly and run so here we can see this ad which is at the query and I don't know if you can see it now you can see it this is not we want for the mobile one okay and we got this also we need to fix this as well we'll fix this okay so we need this ad on the browser we need this in the center of the screen and the width which we set 50px this is not going to work on browser because we need this add text as well so now we have a situation where we need to have two different styles for the same class so for that what we are going to do we are going to override the classes only the properties which we need there so in in this case we need the different CSS styles for our browser so we'll go to the web www .css app.css here we can override the class Fab everything is fine we don't modify everything we'll simply remove the width and the right right 0 and then comes the read apart from this we'll leave everything with 50px we are going to remove this right we are going to have it as 50 percent or rather something like 48 percent so that it can have the uh we have the attached add or not so we have we need to handle that save now with 50px if we remove it we don't know how much width we need so we cannot have this like this the only thing we can do from the common CSS we can remove width directly but now it is not going to work with the mobile dotted mobile what we can do on dotted Maui's app.css there we will have this thing again and here we'll set width to 50 periods we removed width from common we added with 50px to dotted Mouse app.css and we can remove this from browser CSS so now everything looks fine let's see how is we can see this right add a note everything looks fine now next thing is this border radius 50 percent this does not look good on browser right so that means we can go to common we can remove this border radius from here from common and we'll add this only for DOT and Maui for now now we can see this but we need to have some border radius we will have some border radius and some more padding so these we can override in our web assembly browsers uh CSS so here we'll add some border radius so we'll say about the radius something like let's say 10px we need to have it more but this add a note we will make this add a node smaller first we'll have padding so padding let's have 10 PA 1025 page save okay now this add a note we will make it smaller so we can go to home page here on this small we could add some bootstrap class in first we'll say fs6 font size normal performance side small then we'll say FW normal which is point weight normal and we'll have margin from the start which is from left in this case of tool so that we can see some gap between these two fine now we need to have these aligned vertically right this is going down actually so for this what we can do on this nav link we can have this flip flex and align items Center vertical alignment now it looks fine okay now we can increase this border radius and this one border radius let's increase this let's say 25 PX and nice it is looking good now next thing is when we are hovering over it it is showing in this blue color we don't want this blue colors so for that we can go to the common and here we'll say dot pap when we are hovering over it or this is active for both of these cases we will add something that something is going to be first we'll have color white and we'll remove any text decoration text decoration none save everything and now if we are doing this it is fine but we should have some uh something at least when we are hovering over it so let's add a little animation to this that for this when we are hovering over it so we should not have we can have it for active as well so we'll say transform transform and we'll add a rotate animation rotate 360 degree transform save now if we see it is actually rotating but we cannot see it because 360 I can show you there's like something like let's say 180 save you see it is uh the rotation is working but this is happening instantly we should have something for this so for that what we can do on this Fab only we can use transition and we'll say apply this to all changes is in and let's make it 0.2 seconds save now if we come here you can see this is getting applied right now let's change it to 360. save you see this is something is happening right we can see this and we can click on this and it will navigate to the next screen fine first let's see this on the mobile Dot and Maui then we'll work on that scroll bar issue on mobile.net mobile side it is coming here the animation is working we long press it it works like this right but it is on left align so what we should do on this one we'll go to home page where we have this D Flex align item Center here we'll have our justify content Center as well just apply content Center because this was the only item and it was deflex that's why it wasn't this state justify content and this is fine this is working stop it check webassembly again webassembly and we can see this this is fine cool after this this issue you see we need to fix this one for this what we'll do let's go to section [Music] um on this home page where is your description it is here this issue should be on mobile as well okay so for this what we'll do we will not display the complete description here we'll display small part of description the same way we are doing for title for viewing the complete description user can click on it and it will open in the pop-up model so for this what we'll do here first we are checking description after that we'll have a description variable where we will check if the node dot description dot length if this is greater than 100 then what we'll do we'll simply have note dot description and we'll tab first Android characters and then three Dot like this like this and if that's not the case we'll simply display the complete node description node dot description frame bye now we need another condition we will do this thing only when we are on uh browser no on mobile in Grid structure we should have this condition and on mobile when we are on list layout then we should not have this so let's add that condition as well so node.description this condition end and and have it okay if I add here everything then it will be conversion so let's do this if platform dot is mobile I mean if this is not browser and the main goal class this is browser here and Main call class is called 12 that means full stream then we'll modify this description to have the complete node Dot description like this now we should be put we'll use this description to save everything let's Free Run this is browser okay this is coming and even up to 100 characters 100 characters are not good so the size is very odd when it comes to this we have this three if it works on all big sizes oh we don't need to have it on big sizes we can display this complete or we can have it like this only we need to somehow check the screen with when we are coming here this is fine when we are here let's check which breakpoint is this will come here which is actually call md4 12 md4 now we have call sm6 call md4 so the issue is on call md4 then what is it now column before column before let me think how we can fix this case so this is same on column D4 only but uh with size when the size is going to less than 992 92 less than 992 we can see that size here triple 9 92 then we need to fix it okay oh this error is not because of the description this is because of these buttons right hmm okay no no no no it should be because we on this also we have these two buttons okay let's try if we change this description a bit we let's see if we make it smaller foreign let me see what we can do one option is to have overflow Auto on this column only okay right now we can have this only we'll have overflow or towards crawl on this description part only but we can change this we can change the appearance of this scroll bar using some different CSS browser specific CSS but yeah you can check this out I am not I have not used that much I need to Google it and find the actual csses then we can add this but for now I think we can have this only overflow Auto on this Flags grow one plus grow one this one we will have one style here will say overflow y will use Lotto save rerun and we'll check it for both first let's say for browser the same thing actually okay now we can have this we can increase this and everything looks fine now we can click on this then we'll see the complete text we can copy and things are working fine now in this we need to have uh padding on this body so if this was like this then we will not see the actual content right so we need to have some padding from the bottom on this and the same thing will go with the small version let's say this okay it's here this is fine we need to have some padding from this bottom as well so what we'll do foreign right so we can use this page class we can go here on common dot CSS Dot Page we can have a padding bottom of something like I don't know it could be X pave and now we can see this padding and if we go to the browser let's see how it looks on browser like this let's see if my inspect this and we will do this and if we scroll this we can see this so this is looking great fine so I think we are almost there everything is working now the way we thought it should work the only thing is when we first coming to the app then this loading we need to get rid of this loading right let's see again this loading oh I want that home if you remove this like this so there should be this loading then the checking authentication status check authentication state that but we need to fix those after this if we check this on mobile version then we can see it clearly this loading checking out State and all this we need to fix those okay so for this we need to go to our index.htable pages first we'll go to Maui index.html and here this loading this text comes first so we'll have some different loading so I have that ready and I copied that from the bootstraps official documentation page so we are going to use couple of classes from there and the classes we are going to use a testing so we have a div with display flags with the viewport width and height we are using 100 so that it wraps the complete screen and then this div this is for centering MX Auto and why Auto so center of the screen horizontally and vertically both then we have these loading indicators and I have used different colors of primary success danger warning into everything I am using all this let's see this when we run this when the app loads we should see this loading in the center of the screen this you saw that this loading and we'll copy the same thing or the browser version Laser Web assembly version so let's go to web ww root index.html and here inside this div ID app we have this loading progress and all this so we'll paste this we missed one day if this fine save stop and let's run the browser version like this um and it is coming because it is getting it from Cache now we can see this loading right and now we are here in the app cool so loading part is done after this um let's fix the checking or state and that thing so if we go to our index page uh pages index.tracer so we have this common page right in webassembly and browser booth pages index.regions right so let's do one thing let's delete this page from here we don't want any page here and we will simply create this index page inner common components so let's go to Common components pages we'll create a new page and let's call it uh init page initial page let's say unit page and the content we will have this like this slash page title index checking out state unit page is this one we'll go to our Maui project Pages we are going to delete this page or we can delete the pages folder all together we don't have anything in it same thing we'll do with browser Blazer webassembly we'll delete the pages now when we deleted it we need to let's check the main app page assembly username this is fine okay in browser in dotted movie in Main page.saml we have www induct.html X local main main page which is main page Main .racer okay we don't have that index blinking anywhere so it will simply pick up on the basis of the route so it should work as same as before let's try it for both the cases first web we have loading and we have home that means it worked now let's check the mobile version run and test loading we can see checking of state and point everything is still same we just need to change the checking or state and we should handle if we did not provide anything we should display some error there tools for this what we can do we have this name right so the same way we are using this cascading value we have two approaches either we can pass one more cascading value okay which we'll say let's say uh error or name initialize something like this or we have one more approach we can have a common state shared State then we can use that oh let me show you the that satellite state approach so for that what we can have in this common project we can have one let's have a folder we have only single state but still identity folder it should be let's say States and here I am going to add a class class and let's say global app State this is not Global abstain but or we can say initialize State let's have Global Upstate only equal and State this is going to be a class and in here we will have a property is initialized okay we should have this initializing he needs realizing like this and we'll have it a full property that means let me change it to Raw full prophyl rule is initializing and then is initializing like this you can remove this and we are going to have a default value as true because when the app starts is initializing should be true fine after this what we'll do we will Implement I notify property changed I notify property change for this Implement interface this thing so that we can subscribe to the changes we are doing with the initialized and accordingly we can render the UI enter the message and all those and here when we are getting it will be straightforward get the value of this and for setting when we are setting it we will simply use this property changed and will invoke object sender is equal to this and property changed event tags we can do this name of the property like this fine and let's use one more property in which we'll say if there is some error in the initialization in our case if user did not provide the name then there should be some error but for that we will use a full property we use in the label string and we will say error message and parallel message like this uh let's change it to underscore error message and when we are getting the value we do this and when we are setting the value after setting the values we'll simply invoke this property change like this page initializing and this time this is going to be this error message and I think we are good point now let's register this state and this should be Singleton there should be only one instance of this class throughout the app so we'll register it as Singleton in both our projects first We'll add it in our Maui's Blizzard or builder.services.ad Singleton like this and same thing we'll do in webassembly program.cs will register it like this and now we can inject This Global App State but before that let's add it to Imports in our common components Imports we can say using nodes laser Maui don't stage like this and now we can inject this in our init page inject global app State let's call it app state only remove this checking authentication State we'll have a code block Here and Now what we will do we will override on any slides we can have it like this only or we can okay let's have it in its Constructor in Constructor what we will say App State okay it's not going to work because this inject this will works this will work after the Constructor so what we do we should override this in common initialize only on initialized here we'll say abstract dot we have this property changed so we'll do this property changed event asks we need to have event handler for this of type this so we'll have a method here private void let's say on property on App State change something like this changed objects and the property changed event as e like this and when we are this property changed event is invoking we can invoke this thing right and when we don't need this to be subscribed always to what we can do we can simply Implement interface interface is going to be I disposable and then we can have a method from my disposable which is public void dispose and in dispose we will simply thank you remove this event as well by using minus equals fine sometimes phone initialized get gets called multiple times for that we can do like this so if it was already listed we'd remove it if it was not then there will be no effect of this line and what should happen when this happens before that we have this app state so here we'll check what will check first we will check if App State DOT is initializing if this is the case we'll simply have a p or rather have a div class let's say MX Auto and that says yeah like this only then we'll have a p here okay let's through this condition inside this so here we'll say three checking uh state if this is initializing we will do this after that we will have a IELTS condition in that we can check if App State DOT is initializing its false which will automatically come to this case then we'll check if we have some error message if uh node string dot is in our lower white space app State tab state DOT Arrow message like this if this is the case this initializing is false that means app is initialized but we have some error message we will display that error message here so let me have some bigger font let's say S3 class text Angel like this and we'll display this app state DOT error message here okay and if that's not the case then there shouldn't be any else part because in this case we are redirecting user to the next page which is going to be slice home so we should not now we can skip this but still if you want you can have a p we can say foreign we should never see this but let's have it like this this page title this is required for browsers not required but we should have this so that we can set the browsers uh tabs title so this should be only for browser webassembly but we can have it always like this index and on home page we can have it like home and on save note region page we can have it save note save everything now on this home page we are using this app State we are registering App State now we need to provide values for this is initializing an error message right the first oh this should be elsewhere first we need to set is initializing false when we actually got the response so it does not matter if it was true or false we should be okay with either so this thing we have our app dot eraser and those pages from here so when we could not get the name set [Music] first let's inject that inject global app state global app state like this let's add this using two Imports of webassembly and r.net my project as well this thing in four star treasure save everything and now we can use this here Global Upstate App State what they should and here we'll set Upstate dot is not interested App State DOT is initializing real set it to false because app is initialized right after that in this case or maybe let's do it set it here is initializing false we have initialized it over we should have it before this return okay let's do it here only and then in this case we should have error right so we'll say f state Dot enter message will say your name is required in order to proceed with therefore in order to use web or your level required to use the app something like this fine let's do this same o.net Maui we have main dot razor here we'll do is initializing false here then we'll set error message in here um we need to inject App State in here to save everything and now let's run it everything should work now we are on mobile.net Maui let's see it okay first the loader will come from the index.html this one then checking on state then it moved here now let's do one thing let's uninstall this app for the first quiz we will check so this is not small replacer do here check this app this one app info uninstall okay now let's run it again and this time we will simply cancel that name prompt then we should see that error message okay app is coming toward the checking up state please enter your name and we'll say okay we'll cancel it cancel cancel and nothing is happening okay and why so bye guys we're using this right let's go to edit page minute page slash checking what state is this is initializing oh oh my bad we are not okay the thing is we have registered to the changes which are happening inside this App State so it is these changes are happening outside of our pleasure this page basically so that state is does not belong to the space directly so the Blazer component it cannot uh identify it cannot detect that change that's why we are using this property change so here we will simply Run state has changed we are explicitly saying that something has changed so you need to re-render this component let's stop and run this is automatic whenever we are modifying any State Property which belongs to that component only if we have this some property here then it would be automatic process but now this property is changing outside that's why we need to explicitly tell Blazer that you need to re-render something has changed what is this okay then okay it is coming foreign state will cancel it we'll cancel it again we'll cancel it again your name is required and your name is required to use the app like this okay let's re-run this time we will provide the value you can design it further you can have some a delay here and then you can check the cui and make it Center or all those things you can try out for now let me have it up here and redirecting and then we are here everything looks fine cool let's check this out from the Blazer webassembly the browser side okay this is coming Global loader we are on the home because we have data in our local storage let's clear the local storage application local storage and let's play and now let's come back to this page index.ht events loader enter your name we will not enter cancel cancel okay and we can see your name is required to use the app and now if we pre-run and provide the name it should work okay let me add my name okay and now we can see everything okay so everything is still same everything works I showed you two different approaches to handle the states in uh Blazer basically so first we have that cascading value and then second we have this global app State thing okay so I guess that's pretty much all in this video and before that let's clean up the things which we are not using so here just we are using bootstrap but we are not using open iconic we can close this delete this basically app CSS let's remove these commented lines save then we have tab icon this data we are not using this data weather forecast weather forecast service let's delete this folder all together platforms we're using these resources find Services fine shared fine okay let's go to Common this class dot CS we are not using this interfaces we are using models Services States everything is fine go to Common components triple W root CSS box icon main we are using font we are using these background.png we are not using this example JS interrupt.js we are not using this delete we are not using this delete then comes this example JS intro we are not using this delete this then let's come to Blazer web assembly www.sample data folder we are not using delete this in CSS we are not using open icon and delete this inapp.css we have these commented lines let's delete this and open iconic bootstrap icon we are not using this delete we can delete this HTML body as well because we are not using this font save Services we are using shared we are using and fine everything looks great okay if we cleaned this up that's pretty much all for this video so please do let me know in the comment did you find this complete video useful did you learn something new or like this video share this video And subscribe my channel and don't forget to press that Bell icon I will be sharing other cool videos on these complete projects and do let me know in the comment if you want an extension to this video in this poor.net Maui side we are using the Secure Storage only but if I got good response I can create an extension video in that we can use SQL sqlite database food.net Maui for mobile side notes storage do let me know in the comments if you want that and okay that's all for this I'll be back soon with some other cool video and you can drop uh any video suggestions in the comment box as well okay right now
Info
Channel: Abhay Prince
Views: 3,089
Rating: undefined out of 5
Keywords:
Id: pZMO2fKqsZ0
Channel Id: undefined
Length: 405min 46sec (24346 seconds)
Published: Thu Aug 10 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.