‫Okay.
‫So the next feature on our list of requirements
‫is that the application needs a dark mode.
‫And so let's now use the power of CSS variables
‫in order to implement ourselves a nice dark mode.
‫But before we go do that,
‫let's actually fix that small error
‫that we had in the previous lecture.
‫So remember how there, we actually wanted to
‫directly set the new updated user into the React Query cash.
‫So instead of invalidating like here, because with that
‫we then would have the image immediately appear up here.
‫Now there are two problems actually right here.
‫And the first one is that the Query key
‫is not just a string, but it actually needs to be an array.
‫So as I've mentioned, actually many times before,
‫but here I somehow forgot that.
‫And then here in the API auth,
‫So in this function that we wrote,
‫also in the previous lecture, here, we forgot to await.
‫And so therefore, then here this updated user
‫that was returned was always just undefined
‫because we would return this value
‫before this function here had even run.
‫And so with these two changes
‫let's now reload and then try this again.
‫So let's now try my real name
‫and some other image.
‫Maybe, yeah, cabin two.
‫And so let's see if now this updates here immediately.
‫And beautiful.
‫So notice how that changed right away.
‫And so that was exactly our goal.
‫Nice.
‫So with this, we finished this part.
‫Let's delete this.
‫And so this works great.
‫And all right.
‫And so now let's turn our attention to that dark mode
‫that I was talking about earlier.
‫So in the styles.CSS file that you got in the starter files,
‫you should have had these
‫CSS variables for dark mode.
‫So hopefully you copied them right here
‫into this global styles file when we did that.
‫And if not, you can always just go back to the starter files
‫and then open up styles.CSS,
‫and there you will find these.
‫Now what we want to do now in order to implement dark mode
‫is to set different CSS variables
‫for different class names on the HTML element.
‫So basically right here in our elements,
‫we will have one class for light mode
‫and one class for dark mode.
‫And so then according to that class
‫these different CSS variables will apply.
‫So let's grab them here.
‫So all of this.
‫And so notice how the CSS variables are defined at the root
‫which is actually exactly this element.
‫But now we want these ones here to apply
‫only when there is a light mode class.
‫And then the ones that we just copied
‫with a dark mode class.
‫Now these blue ones here will actually be the same,
‫but then everything else here is actually gonna change.
‫So the border radius will also not change.
‫But in any case, let's now write this and,
‫which basically means the current selector
‫and then with the class of dark mode.
‫So then let's place that there.
‫So for some reason this didn't get prettified by Prettier.
‫But anyway, let's now then place these ones here,
‫again with the end, which is basically just this root,
‫and then with the light mode class.
‫And so all of this here should be inside that.
‫Now here.
‫Actually let's also place this one into light mode.
‫So,
‫that's right here.
‫Because in dark mode we will then make all our images here
‫with a bit less opacity and give them some gray scale
‫so that they don't look so bright on a dark background.
‫Now, all right.
‫Let's maybe grab these blue brand colors
‫and place them down here.
‫And so these styles here, they stay the same.
‫So this color and also the border radius.
‫But then for the dark mode we have these colors.
‫So not only these grays,
‫but also these shadows and this backdrop.
‫And for light mode, we have this.
‫Now, all right?
‫So again this selector here is basically the same
‫as writing this.
‫And so that then means that it needs to be this selector
‫and at the same time the light mode.
‫So no space, but really this.
‫And actually we also want to apply this
‫when there is no class at all.
‫So basically making this the default.
‫And so we can just write this.
‫And so then this is basically just regular CSS,
‫just with the added thing of nesting.
‫Now I'm not sure why this is not getting formatted,
‫so maybe we have some error in our code.
‫Let's see. But maybe not.
‫And we can also check out here the output from Prettier.
‫And so everything seems to work fine.
‫So maybe it just cannot really format here this kind of CSS.
‫but that's no problem at all as long as it works.
‫And we can actually immediately check if it works
‫by manually adding that class here.
‫So we can write "class" and then
‫"dark mode."
‫And beautiful.
‫So here you are seeing our dark mode
‫for the very first time.
‫And so again, that is working because now
‫all the CSS variables that we had before
‫were replaced with these ones.
‫And since we are defining all of the colors here
‫all over the application based on these CSS variables,
‫then all we have to do to implement our dark mode
‫is to switch these CSS variables.
‫And again, we switch them by simply changing the class here.
‫So if we write light mode.
‫then we are back to these colors right here.
‫Now, all right.
‫And now of course we want a way of changing this class
‫right here in our application.
‫And so for that we will add a button here.
‫And let's actually start by doing that.
‫So right here in our UI folder,
‫let's add a component called "dark mode toggle."
‫And then here all we are going to return is another one
‫of those button icons.
‫And then for now, here, let's just place this outline moon
‫just like this, basically showing
‫that we want to switch to dark mode.
‫So for now, of course this button won't do anything,
‫but let's still add it here to our header menu.
‫So here
‫another list item, and then here
‫we add that toggle.
‫And so then there we get that nice additional button.
‫Now, okay.
‫But now of course it is time
‫to actually make this button work.
‫Now we need the information whether dark mode
‫is activated or not in multiple places in the application.
‫So not just here in this toggle,
‫but for example also in this logo.
‫So we will have a different logo when we are in dark mode.
‫So basically what this means is that
‫we want things to change on the screen
‫whenever we change to dark mode.
‫Not just the colors themselves,
‫but really the entire state of the application
‫needs to change so that we can then also
‫display a different icon here.
‫So that means that we need a state variable
‫and that state variable needs to be accessible
‫in the entire application because, again,
‫we actually need that information both here
‫and here in the logo.
‫And maybe in the future we might even need it
‫in some other places.
‫And therefore let's now create a new context where
‫we will store that state
‫and then provide it to our entire application tree.
‫So this is in fact gonna be the only piece
‫of global state that we're gonna need to manage ourselves
‫because all the other state, as we already know,
‫is being handled by React Query.
‫So all the remote state, which is usually most of the state
‫and most of the global state that we're gonna have
‫in an application.
‫But again, here we now actually do have one
‫local global state.
‫And so for that, let's now create,
‫as I mentioned, a context.
‫So we actually don't even have a context folder here yet.
‫So let's create that.
‫So new folder "context."
‫And then in there let's create our dark mode context.JSX.
‫And so now in here we will follow exactly the same recipe
‫that we have learned about before.
‫So we will start by creating a new context.
‫So the dark mode context
‫with create context from React.
‫And then here we will create a component
‫which will be a custom provider.
‫So a dark mode provider which will receive
‫the children prompt.
‫And then this is where we will actually store our state.
‫So is dark mode
‫and set is dark mode.
‫Now here we could of course use the use state hook
‫that we have used so, so many times.
‫But instead, let's actually use that custom hook
‫that we created earlier, which is use local storage state.
‫So use local.
‫And well, I think we have it here.
‫Yeah.
‫So this custom hook we built it earlier
‫in some other part of the course.
‫And so I just placed that here in order to reuse it.
‫So this basically sets the state
‫and then also synchronizes it with the local storage.
‫So use local storage state.
‫Let's bring that in then, as well.
‫Let's just copy that.
‫And then from hooks,
‫and there we go.
‫So the signature of this hook is very similar
‫to the use state hook, and so it returns the same things
‫and it also needs an initial value.
‫So let's for now make it false.
‫And then we also need to give it the name
‫of the key in local storage.
‫So let's just reuse "is dark mode" here.
‫Okay. And now here, let's then actually return
‫the dark mode context.provider,
‫which will then return to children.
‫And then as always, we pass in the value.
‫So a new object with is dark mode.
‫And then let's also actually create here a custom function.
‫So just toggle dark mode.
‫And so all this will do is set is dark mode
‫basically to the opposite.
‫And so then this is the event handler function
‫that we pass into our context.
‫So this is the first part of that recipe that I mentioned.
‫So that's the provider.
‫And then remember how we also always then create
‫our custom hook here.
‫So use dark mode, which then basically
‫directly consumes that context.
‫So we store that in context with the use context hook.
‫So dark mode context.
‫And then here, let's just make sure
‫that this hook is always used in the right place.
‫So if this is undefined, then you want to throw a new error.
‫Dark mode context was used outside of dark mode provider.
‫And if that doesn't happen,
‫then we can just return our context value.
‫And then in the end we just export the dark mode provider.
‫So not the context, but the provider.
‫And then use dark mode as well.
‫Now, okay, but that's actually not all
‫because all this does is to set the state.
‫So that's already useful, but it doesn't really change
‫the application here to dark mode.
‫Because remember for that
‫we actually need to add these classes here, right?
‫But let me show you what I mean by that.
‫And let's start by using this a new context
‫and this new state here as it is right now.
‫So let's come right here to the dark mode toggle.
‫And then here we can
‫use all those values.
‫So we can use is dark mode
‫and toggle dark mode.
‫And we get that from use dark mode that we just created.
‫And of course that's not going to work
‫because first we need to actually provide our provider.
‫So now we get exactly that error message
‫that we specified earlier.
‫So we use this context outside of the provider.
‫And so let's start by adding that here to the entire tree.
‫So maybe even right here.
‫So dark mode provider and then the closing tag
‫at the very end of the tree.
‫All right.
‫And so let's go back.
‫And then here is where we add that toggle dark mode
‫to the on click prompt.
‫And then here we use the information,
‫whether we have dark mode or not
‫to display a different icon.
‫So if we are in dark mode, we want to change to light mode.
‫And so let's use a different icon here,
‫outline, and then let's use the sun here.
‫Not like this.
‫But there we go.
‫So let's see.
‫And indeed that is already working
‫so we can toggle now between these two states.
‫And so let's do the same thing here also with the logo.
‫So I mentioned that there, we also need that state.
‫So let's come there.
‫And then here we do the same thing.
‫So is dark mode.
‫So that's all we need right here.
‫And then here, let's define the image source
‫based on whether there is dark mode or not.
‫So if so, you will have one image
‫and otherwise we will have this one.
‫All right.
‫And then this other one, I think it's just called logo dark.
‫So that would make sense, right?
‫And so there it is.
‫So logo dark, and then here we just use that.
‫And so indeed the logo now looks a bit different.
‫And if we toggle back,
‫then notice how at least the text here changes.
‫So these two components now respond to the dark mode state
‫but now comes the time where we then need to
‫actually also change here this class name.
‫And so let's go back to our context here
‫and do that actually right here.
‫So for that we can use an effect.
‫Let's maybe do that here.
‫So use effect.
‫Which should basically run each time
‫that the is dark mode changes.
‫And now this is very easy.
‫So if
‫is dark mode,
‫then let's do some dumb manipulation here.
‫So document.documentElement,
‫which is exactly that root element.
‫And then on the class list
‫we can now manually add that class.
‫So dark mode, in this case.
‫And we remove
‫then the class of light mode.
‫And immediately you see it working
‫'cause we are actually right now in dark mode.
‫And so this is already doing its job.
‫Now let's just do the opposite.
‫So else we add
‫light mode and remove the dark mode.
‫And this is actually it.
‫This is all that we need.
‫And so let's check it out.
‫Let's click here.
‫And indeed here, here the class then changed
‫and everything else changed as well.
‫Beautiful.
‫So look how nice this dark mode here is
‫especially here in the tables and everything.
‫And yeah, basically every modern web application
‫needs a light mode and also a dark mode.
‫And so that's why I decided
‫that I wanted to add this feature
‫to this most real world application
‫that we're building in this course.