React JS CRUD Actions using REDUX Pattern MUI Design & JSON SERVER API

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello friends welcome to my channel hiratakis in this video we can see how to implement credit actions in react.js using Redux pattern material UA design and Json server as jpa okay so before going to the implementation let me provide one demo so this is my application in this listing I have populated list of company information now let me try to create a new record so this complete design implemented using this material UA components and also we have included this validation so the first three fields are a mandatory field and also we need to click this agree it's defaultedly checked if I'm unchecked so this Summit button also disabled okay so let me click this one let me enter some values Test Company and email and next in this company type we have seen this emergency under domestic so let me choose this domestic so let me click the submit button see so the new record is created successfully and I'll see this reflected in our listing okay now I am trying to update this record so you know the existing data is loaded now I am trying to change this type and also this company name okay so let me click the submit button see now company updated successfully and also in this listing you can see this TS limited and also the cmnc okay now let me delete this record so we are getting this confirmation popup on same click to ok we are getting the message company removed successfully and also it is reflected in our listing okay and in this listing we have included this page nation and also the loading spinner in the initial load so this is all about our demo now let me start our implementation okay the first step is I am going to create one brand new react.js application using this command so basically it will take some time so look like our application is created let me open in our vs code so this is my application company app and the next step is I am going to create the record files that includes the components and supporting files for our Redux implementation so inside the source folder I'm creating one new folder so similarly I'm going to create two more folder the second one is for the index implementation alone is handling the data next let me create one component our common name is company here I am going to use the Cs Sub C stateless functional component for defining our components so initially we can have one due tag inside that I just added one headstone tag and if you are using this sfc command make sure you have to install this extension simple react Snippets okay so otherwise it won't work so next we can create the files for our Redux implementation so the first one is action second one is reducer and the third Only Store also I am going to create two more supporting files for this action Oneness action type and another one is action creator next let me move on the data here I am going to include one Json file so this file actually acting as our main data source for our Json server API okay so we have created the record files and the next step is we have to install the required packages so the first package is material wave okay let me execute the command once it is completed we can install the next package for material UI icons okay this is completed so let me execute the next command then this react router Dom so this is for implementing the router so the react router Dom installation in progress and the next one is react hostify so this is for showing the traditional alert at the final one is react Redux it includes lot of packages the first one is Redux then react Red X the next thing axis and Redux logger and the final one is Redux JS toolkit okay so if you want to know about all the integer libraries I have created the separate series for index so you can find the link from our video description now let me execute this command okay the installation gets completed we can see in this package.json see all the libraries are included okay and the next step is we have to run our Json server APA so first we have to install this command npm install Json server so basically it will install the Json server Global in our machine so I already have done this step so next I am going to run over APA using this command from our application let me create one more new terminal and here this Json server up to us this is the syntax then I am going to use the particular Json file so I have provided the complete path so finally I am going to execute our AP in the port of 8000 okay so let me execute this one So currently it's don't have any data so let me Define some data also I'm having some data in the handy manner so let me include it here okay so in this company I'm going to have six Fields the first one is ID name email phone number address and type so I added three records so let me save this one and this is our AP endpoint okay see it is returning all the data so next what I'm going to do let me focus on the designing area so in our component So currently I just included this due tag only here we can start descending our table first let me declare the columns constant here let me include the objects one by one similarly let me include six more items okay email phone number address so let me include the display name also address company type finally we can include one more object for the action okay so let me save this one and here we can remove this headphone tag let me include this paper element it's from our material UI so inside that let me include this table container add them table so inside the table I am going to include table head and the table body so this all elements belongs to our material way so in this header side we have to include this table cell so let me generate the for Loop for this columns array and in this key we can use column dot ID and in this text we can use this column.name let me run this application npm start so this content actually loading from our app component so this is a kind of template so we can remove everything also we have to Define our routing here so let me include this browser router so instead that we can use this routes sensate the routes we can Define our in digital routes one by one so in our case we can register our company components here okay so in this path we can keep it as empty and in this element we can use our company component okay so let me save this one so here this logo is not needed so that's what we are getting this morning actually we are not using okay see now our table header is coming so let me include the add button so inside this paper element let me include one due tag it's in this above one I'm adding one button okay and the variant we can use content and let me include some margin I'm including for this due tag also also we can include in this paper also okay here I am going to use this CSX so let me save this one says you know we can see some mild border and also this add new button also coming okay and in this header first we have to include this table row actually I missed this one so it is just a TR only okay and let me include on Style and in this table cell now it is somewhat fine okay next in this table body uh we have to fetch the data from our APA and we need to populate it here so and also if you are clicking this button we have to open the pop-up so let me Define on function here one click function add so let me Define this function and I am declaring one usted variable so default value let me forget as false okay so this is related to open your pop-up and we can Define our pop-up so after this paper control let me include this dialog so this one also belongs to our material UI so in this dialog I am going to include dialect title and dialog content okay and in this title and saying create company so in this dialog content we can include all the form controls so first I am added one form tag here I'm going to use the stack then I am going to include the text field okay so text field is nothing but our input control only and here the variant we can use outline and the label we can use name so let me share this one and in this dialog element I'm going to use this open so the value we can use the same open and also closing this popper we can use this on close here I am going to include one function close pop-up so let me copy this one false so similarly we can create one more method that is Swap and popup okay and the value is true so in this function add I am just calling this function so let me save this one so when I'm clicking this button now we are able to see one small pop-up so let me provide esm okay this is fine so the similar way I'm going to include all the controls one by one so before that let me initiate all the U State variable for the individual controls so the first one is ID and the even name is ID change the default value is zero so let me copy this one I added five more used variables but the second one is name and the even name is name change so the default value is empty then email so in this email also the default value is empty and the phone number and address also same and the final one is type so in this type I am going to provide two options m1c and another one is the domestic so let me provide the default value is human C okay this is more than enough for defining the controls I just included this name this ID is not needed so the reason is I am going to generate the ID in this Dynamic manner so first in this name control let me provide the values name so this is nothing but our U State variable okay and in this on change we are assigning values into our U State variable okay okay this is fine so let me save this one the same way we can include the other controls also so our second control is email then phone number so the changes are email and the function is email change and the label email so similarly for the phone number we can use this phone then four chains and the label is formed under the next two field is address change and this is the text area control okay so we can provide multi-line and maximum rows 2. and the minimum also let me provide two okay so then the size will be increased at the next control is kind of a radio button for handling of our company type so our company name is Radio group okay so here also we can use this value and this change and the value is type and the function name is type change and in this group I am going to provide two options so let me use form control label we have to provide value so let me provide the default value is MNC and the control we can use radio and the label we can use same MNC so let me include one more option and this first radio button let me include the color this is not mandatory but showing some difference I am including the success okay so let me save this one see now MNC under domestic so we need both in the same line so in this radio group we can include this raw option see now it is coming like this okay next I am going to include our submit button and also this agree terms so let me copy this form control label just added here and this value is not needed and in this control side I am going to use checkbox okay and in this label agreed terms and conditions and in this set I am going to use phone used it variable create um just let me Define this one a key term and a term since so the default value is we can provide true also let me copy this function so in this hard change event so e dot Target dot sector so here we can expect true or False only the value point of view and finally let me include the button type submit so let me save this one see the response okay the button is coming so let me include the variant also so let me save this one so our design is fine okay and the next thing is uh if I'm unchecking this accurate terms and condition make sure it should be disabled so it is a small condition online I'm just including this disabled we can use the same agreements okay not equal to agree terms see now it is disabled so if I'm clicking this one it is enabled mode okay so next we can include the validation so let me make this name email and phone number these are the mandatory fields for that first I am going to include this required okay after that we can use this error option and in this error I am going to include the condition for the name dot length if it is 0 then I have to show the error see now so in this border we are able to see this red color right when I input some value so it is automatically changed see so the same change I am going to apply for this email and the phone number and in this form I am going to write an event and submit and the function name is handle Summit so let me Define this function see if I am clicking this one so the post is not submitted okay it is simply blocking because this is the mandatory field so next in our handle Summit function I'm just blocking the default Behavior driven to default so after that let me declare one constant variable so this is one of the object here I am going to include all of our U State variables okay ID name and that I don't miss email then phone number address and the final one is type okay so let me keep this constant variable into console lock now let me enter some more values just test 13.com some numbers or the type defaulty DCM and C let me change this into domestic and in this console.log if I am click to this submit see we are able to see all the datas okay so this is here the ID is the only Auto generate field other than that we have all the values okay okay now we have the data so the next step is be how to call our AP okay so as I mentioned I'm going to follow this redx pattern so this API handling everything then from there red x side only okay so now let me focus on the Redux area so we can start from our action type okay so in this action type I am going to declare the constant variables so that is used for defining our actions okay so let me do one by one export constant so the first one is for loading the listing we have to make a request so let me provide make request okay and in this request we can expect two kind of response one is the fail and another one is the success so request get uh sexes so similarly we can expect a failure scenario also next let me move on the action side accents are a kind of functions it is returning an object it is returning an object here we have that type property so in this type we can use this make request okay and in this actions I am not going to pass any data so this is fine okay and the second one is get all request success so in this axis we will get one response that is our list of campaign information began pass this data through the payload and the third action is for the failure scenario so in this failure scenario we will get the error information so we can pass this error also through the payload okay so let me save this one next let me move on the reducer side okay so in this reducer let me Define our initial state so this is the object so the first properties is loading so this is for showing the loading spinner so let me provide the value is false and the second one is company list it will hold the complete company information and the third one is company object so this is for handling the individual company information so mainly used for the edit scenario under the final one is crr message so default value is empty if there is any error we can include in this error message section okay now let me Define our reducer also company reducer it's having two parameter the first one is state so the default value we can use the initial state and also the action so let me format this one and here I am going to use the switch option so in this switch I am checking this action type so next we can use the case if the case is make request then we can return the same state also ascending value to our is loading okay so let me make this into true and let me format this one and our next case is request get all success so here also I am returning the default State and then I'm making this is loading interfalls finally I am ascending value into our company list okay so we can get the company list from our action action dot payload so let me format this one and the final one is for the failure scenario get all fail so here also we are returning the default State I am making this is loading as false and in this company list let me Mark this into mtra and in this error message we can get the error information from the payload so let me add like action.payload at the end we can provide the default return States okay we finished our reducer side also next let me move on the store here let me Define our store equal to configure store so in this store we can register our reducer okay and our reducer name is company reducer also we can include the middleware in our case we can use this thing and another one is lager so let me save this one so actually in our case we have only one reducer in case if you have more than one reducer we have to use the combin reducer option anyway let me implement it here constant root reducer so this is the variable and here let me use this combin reducer okay so in this combined reducer let me have an object company then this company reducer okay next thing you should have directly using this company reducer we can use the root reducer so finally we can export this store export default store okay so let me save this one okay this is fine next we have to use this store in our app component okay because that is the base component for using the store we have to use the provider element so that is provided by our react reduction line and here we have the store option so in this store we can use our exact store okay I think it is not imported maybe I can provide some other name Company Store foreign store okay so let me save this one next let me move on the action Creator okay so this action Creator is kind of function so it will return the another function okay so let me Define it gets all customers so this is the kind of function and it is returning another function send this function first I am going to dispatch the make request okay that means our make request action it's don't have any parameters next we can call our APA for that I am going to use this axios okay so the first one is the get method we know our AP endpoint also let me use it here then so similarly for the error scenario this response okay so similarly in this yellow scenario we will get the error and once we have this data we can dispatch our get all request success action okay here I am just passing this list of companion formation similarly in the cro scenario we can dispatch this get all requests fail action so here we need to pass the error message that's it so let me format this one okay this is fine next let me move on the component side so here I am going to create two more functions the first one is we are converting our state into props okay so the method name is map state to drops it's having the parameters state and here so the company state it's a kind of object only from the whole state we are going to access only the company object okay here this company is nothing but the same object they have used in our store okay and similarly let me create one more function map dispatch to props okay here the parameter is dispatch so in this dispatch we have to call our action Creator okay get all I provided the name is Getwell customers so actually I have to change this into a guitar companies next I am going to use the connect option from this connect we can call both the functions map state to props and also this map dispatch to props and finally we are passing this common on it that's it okay the concept is very simple for our company component we are passing the props using this connect option okay so let me put these props and let me include this EMT dependency also at the end we can call this function get all companies okay or this one load company okay okay this is fine and similarly we can access our state also so next let me move on this table body props Dot company States dot company list so we can check it from here yeah this is the campaign list only if it is having the data I'm generating the for Loop so here we can get this row and also this index so here I'm going to generate our table row okay so the table row in this case section we can have this index value next let me including this table cell so that is nothing but our 3D only okay product name so let me save this one see the response okay the data is not loaded let me verify if any error okay so there is no error but in the log we can see this make request action is executed and other than that nothing is executed okay so let me confirm okay this is the problem so by defining our action this action type we have to use the unique value okay so in this get dull request is access I have to use this action type so similarly in this fail it should be like this now let me refresh once again okay we have the data uh for the first field this should be ID but actually I have provided us the name so that's what it is binded like this so let me change this one ID then email phone address type okay email phone address and type and the final one is for the action so let me how this is the empty it's you know so the data is binded so let me check this address also okay this is the Capital One okay this data also binded and for this action we can include two buttons edit and another one is the delete okay here the variant is combined and the color we can use primary [Music] let me save this one okay the date is coming so similarly I am going to include one more button so this is for delete okay this is fine for the space we can include some Style from our Global Style let me include button margin two pixel okay okay see so the design point of view it is fine and next let me focus on this add new okay so already we have completed this design validation we have the data also so let me do some changes for our Redux side okay first in our action type so the first action type is request add success failure scenario we can directly show the error message from our action creator and for the make request in our case we are opening the pop-up right so what I'm going to do let me write one action open pop-up next let me move on this action we can copy this one add request it's having the input data so through the payload I'm going to transfer the same data okay and in this type we can give request add success so similarly let me create one more action open pop-up it's not having any parameter and the type is open pop-up and payload there is no data so let me say this one so next we can move on the reducer side first we can include for this add success okay so so the case is request add success okay in this scenario I am just returning this actual State uh in this is loading there is no change and since this is a success scenario there is no error message and other than that we have some changes okay so let me do that so through the payload we will get to an object that is nothing but our input data only okay action dot payload okay once we have this data in our company list so let me include the current state value after that I am going to include our new object okay okay this is fine in this add scenario we have to do one more change let me tell you so in this input area we not provided any control for this ID field because this is the auto generated column okay so if you are checking in our reducer side in this input object for the particular ID we will get the default value is 0 so then we have to calculate it manually so what I'm going to do first we can take the maximum ID let me declare one more variable maximum at equal to mat.max so the state DOT company list ID okay so in this next Lane we can assign the value for this ID next let me move on the action creator so here already we have this guitar company function so similarly I am going to create one more function that is create company okay it's having the parameters data so this is the object and here this make request is not needed and this is the post request okay and the URL is same but the only difference is we have to pass the data okay next once our action is completed we can dispatch this add request action okay and we need to pass the same data that's it another thing is we have to notify the user by displaying the alert message for the alert I am going to use the toaster okay so the package already installed so the configuration point of view first in our app.js after this browser router we have to include this toast container okay and also we can specify the position so let me choose this top right okay next we have to include one CSS reference let me go to our index.js here I'm just included okay next in our action creator I'm going to use this toast success company created successfully so in this failure scenario we can use the same toast alert so the text is failed to create company due to we can provide the exact reason okay payroll dot messages so let me format this one next let me go back to our component side so in this component we have this handle Summit so from this handle Summit we have this complete object so the next thing is we have to dispatch the action so already I defined this dispatch so using that create company this is the action Creator method and let me pass this object also and once the action is completed make sure we have to close the pop-up so let me save this one I am trying to create a new record so let me click this save button see now we got the message company created successfully and the new record is reflected in our listing also okay so that means we have completed our create record functionality so if you want to verify the error scenario I'm just providing the wrong URL providing some dummy data see failed to create the company due to the status code is 404 because the URL I have provider it's not a valid one okay so let me close this one so next let me focus on this 80 delete functionality so before that let me include the pagination for this listing so this is not going to take much time in our component side after this table container let me include this table designation okay it's having some property we can include one by one so the first one is row per page options so this is the array let me provide some values Phi 10 20 okay see now it is coming and also we can see some on different value so the next property is proper page for this Roper base let me declare one use State variable so the default value let me provide five okay similarly I'm going to declare one more use State variable so that is the page so the default value let me provide zero okay next in our page Nation side we can include the values this Roper page next one is this page for that we can use the same page rather than this count we can get it from here okay this in this company list dot length added in this component I mean we can consider this is the due okay so let me save this one okay this is loader next we have to handle two actions one is this row per page change and another one is the page change okay so let me declare two more functions so the first one is handle page change okay and the next one is handle proper page scenes so in this handle page change we will get this event and also the new page that's the parameter so here I am going to set the values okay for the page change let me use this new page so let me format this one next in this handle Roper page change if the parameter is C event we can use this row per page change event Dot Target dot value and also we need to set this base change value is zero okay this is fine next let me go back to our page Nation and here on page change we can use this handle page change similarly on rows per page scenes we can use so let me save this one so finally in this data binding site I am going to use the slice option so we can save this one see now it is fine so in case if I'm changing this into 10 so if you want to verify we can include the options 2 also okay now see so if I'm selecting these two so in this past two page the two record is loaded in the second page we have the another two records so similarly changing this into term so totally we have only four records so it is loaded in the single page okay so now we have done our pagination also next let me focus on this edit function okay so in this table I already included this delete and edit button here we can bind on event this row dot ID so similarly in this delete also we can bind the event handle remove now let me Define both of the functions similarly for this delete also yeah remove so next in this edit scenario this edit scenario also we need to open the pop-up so let me include it here and before that I am going to have two more used it so the first one is easy edit so the default value is false and the next one is title titles means so the default value is create company next in this add scenario I mean this function at let me provide so this is false and in this title also create company okay similarly in this edit scenario so this is true under the title is update company next in our pop-up so initially I have provided a hard code value so instead of that we can use the title variable okay and one more thing so in this pop-up open time I actually am dispatching this open pop-up function okay it's don't have any parameters so in our reducer side so let me include some changes if it is open pop-up let me return the same state and we now need to worry about this is loading so in this company object let me mark this into empty upset okay so let me say this one so initially the data is loaded if I'm clicking this add new or pop-up is open and our text is create company similarly if I am clicking this edit so the text is changed into update company at the same time we have to populate the existing campaign information okay for that let me do some changes from our Redux side let me start from our action type I am declaring some variable here a request get by code next in our action site get by code success okay so in this action basically we will get the company offset so the object I am passing to over payload okay so let me change this type also request getby code success finally in our reducer side let me copy this one I'm checking this request getby code is access so I'm returning the same state and this is loading is not needed so instead of the company list I am going to use this company object so whatever data I'm getting from the payload I am adding this into our company object okay so let me save this one finally in our action creator let me create one more function get Company by code okay and it is having one parameter that is code and this initial request is not needed so let me remove this one are the requests get request only but in this URL we have to pass this code so in this past your response we will get to an object and here let me dispatch our get by code success let me pass this object so if there is any failure let me show an error message failed to fits the data so that DC enough as of now next let me go back to our component side so here let me access our State using the use selector option editor object equal to use selector state here this state then our object company and finally our company object okay so let me save this one next let me declare one more use of it hook so here in this dependency side let me include our edit object okay and in our hand related function let me dispatch on action that is our get Company by code and we need to pass this code also next let me get back to this UCF right so in this hook I am trying to access this edit object before that let me verify the state DOT company okay looks like some spelling stick so here let me check it's in the particular object whether we have the data object.keys and this edit object if it is more than 0 only I am just accessing so in this else scenario let me clear all the used in variable okay so for that already I returned the function see so I just to provide the default values only so let me copy the same thing if I'm halving the data I have to assign the values okay first of all this ID and the second one is for name and the third one is for email next to this phone number then this address and the fine lunis type so let me save this one so now if I'm trying to edit the first record okay the data is not loaded okay I'm getting the error let me verify so in this UC effect receive the final argument is not an array yeah now I understood so the dependency we have to include in this array format only okay let me clear the error again I'm clicking this edit see now the data is loaded if I am clicking the second record so now we are able to load the existing data next let me focus on this update functionality okay so this is not going to take much time because already we have done for the ad so let me go back to our action type I am declaring two variables okay one is for update and another one is for delete next in this action point of view became declared through actions and the first one is for update request and the second one is for remove request okay and in this type also request update success and requested delete success and in our update scenario we have our parameter is an object similarly in this remove request for parameters just a code only okay the same thing we can pass to our payload also so next let me go back to our reducer side and just copied this add section first let me check the type add update success I am getting the data from our payload here no need to calculate this maximum ID so let me remove this one so instead of that we have to find which area we have to update okay so what I'm going to do let me declare one more constant variable final data okay so then this state DOT company list let me generate the loop here I'm just returning this item.id a underscore data.id means I am just returning this underscore data okay otherwise the existing record that's it so this final data we can assign into our company list so that's it next let me get back to our action creator I am going to create one more new function for the update company so in this update scenario we have to pass the ID also in this URL data.id and the requested type is put request once the action is completed we have to dispatch this update request and the message is company updated successfully and the failure scenarios failed to update and we are providing the exact reason so let me save this one so finally we can get back to our component side so here already we have this handle Summit function here I'm just checking on condition this is edit value is true then let me consider this is the update other ways this is an add scenario so in this edit scenario we can call this update company so let me format this one now let me try to update this one TS infotech and change this type also domestic see company updated successfully but in our listing it is not reflected so let me verify so in this reducer side we have to include it like this because it will already return the array only okay now let me try to edit one second see company updated successfully this message is updated so let me take the another one record so NT Tech and this domestic I changed all the fields see all our got reflected so if I'm changing this into MNC company updated successfully so our update functionality also working fine so the final one is delete so in this delete I already added this action type and also this action so next we have to move on this reducer side so in this reducer said let me copy the existing content and in this case let me check request delete success so here this data is not needed so instead of the fill your final data and let me add filter data okay next in our company list I am going to apply this filter so return data Dot ID sm.id okay it's not action.id action.payload okay this is fine next let me go back to our action creator so in this creator also let me create one more new function for remove company okay and the input is code action type is delete and this data is not needed through the URL we can pass this code so once the action is completed we can dispatch the remove request okay okay let me pass the same code but the message is company removed successfully failed to remove so finally in our company.js so finally let me come back to our component side so already I have this handle removed so here let me dispatch this remove company also I'm just passing this code okay and before that let me include one confirmation do you want to remove if it is yes only I am proceeding for the delete okay underscore filter data is assigned but the value never added okay and this confirm also not supported first in our reducer side yes we need to change this filter data instead of this final data so the warning gets gone and the error I believe we have to use window dot confirm so now if I'm clicking this delete button so do you want to remove one same clicked okay so company removed successfully and also it is reflected in our listing okay all the accents are working fine now we successfully completed this create update delete and read actions so before closing this video I am going to cover two more small topics the first one is so in this initial load how to show the loading text or the loading spinner and also if there is any error how to show the error message from the initial load itself okay for the state point of view I mean this reduction there is no changes because the initial State itself we have included this is loading and error message using these two variables only I am going to include our changes so in our company.js so here I'm going to include one more due tag okay so instead that let me include one hashtag also so the default value I provided just loading okay and here let me check like props Dot company that is loading so in this scenario I'm showing this text okay other ways so our current content that's it okay it's loading showing any error okay it should be prop stored company state now let me save this one see so the loading text is coming and it is closing very quickly so let me include some timeout for showing the difference so let me move this AP call into our timeout so in this real-time application basically takes some time for the test data we have just four records even this is the Json server API so it will return the data very quickly so manually I have included some timeout okay so see now see initially it is saying loading after some time the record is loaded fine okay so in the same area instead of the text we can use the loading spinner also so similarly if there is any error so that also we can handle so let me copy the same content so instead of this yes loading let me use the error message so whatever error we are receiving I am just displaying here okay so now we are not getting any error so we can make the error manually just providing invalid URL so the request you failed with the status code of 404 here I am just showing the error message in this real-time application you can include some Styles okay so then it will be much better so let me uncomment this one so if I'm refreshing one second so our datas are loaded fine okay okay now we are in the end of the video still if you have any doubts or clarification please post in the comment box and also please don't forget to subscribe my channel so in my next video we can see one of the interesting video thank you thanks for watching
Info
Channel: Nihira Techiees
Views: 9,770
Rating: undefined out of 5
Keywords: react js tutorial, get form data in react js, post request making in react js, api handling in react js, recat js crud operations, crud operations in react JS, JSON Server rest API in react js, react crud operations, react crud actions using redux, react js material UI design, React js crud actions using redux and json server api, api handling in react redux, handling post request in react redux, loading spinner implementation in react js redux, redux implementation in react js
Id: Lr0Sy8xE1hY
Channel Id: undefined
Length: 75min 24sec (4524 seconds)
Published: Mon Aug 07 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.