Now that we have our API endpoint for transactions ready, let's go ahead and let's convert that API endpoint into a set of reusable query hooks. So I'm gonna go inside of my features folder and I'm gonna copy and paste the accounts and I'm gonna rename it transactions. I'm only going to focus on the API folder for now starting with use get accounts which in this case in this case is going to be use get transactions. Let's rename the hook use get transactions and now let's go ahead and let's import useSearchParams from next navigation and inside of here let's get the params using useSearchParams. Let's get the from using params.getFrom or an empty string.
To is going to be params.getTo or an empty string and const accountId is going to be params.getAccountId or an empty string as well. Now we're going to change the query key to be transactions, but only for fromTo and accountId. Like that. And now we're going to modify this API call to go to transactions. We're going to open the GET request and we're going to add a query here to have from to and account ID.
And our error is gonna say fail to fetch transactions. I'm also curious about this right here. Now that I think about it, Perhaps it might not be a good idea to make our key unique based on the query. So I'll just add a to-do, check if params are needed in the key. We're going to come back to this later, but this worked fine in my original implementation but I'm a bit curious about it but we will explore that later.
Now let's go ahead inside of the individual use get account and let's rename it use get transaction so inside of use get transaction right here let's rename the hook use get transaction and the id prop is the same but the query key and the API and the error should all be transaction. So this should be individual transaction and ID and this API request should go to client API transactions ID and this should be failed to fetch transaction. There we go. Let's go ahead and let's use the use edit account and let's rename it to use edit transaction. Let's rename the hook, use edit transaction.
And let's replace all instances of accounts. So starting from the response type into the request type, the mutation function here and let's just leave it like this for now. So just these three instances and let's change it to transactions like this. So client API transactions, client API transactions, client API transactions, just like that. The JSON here is correct, we don't have to worry about that because we are using the correct response and request types from transactions here.
Now what we are going to invalidate here, first of all let's fix the success message so it's going to say transaction updated and this will be failed to add a transaction We are going to invalidate the transaction ID key and we are going to invalidate all transactions here. So this is why I'm curious about our useGetTransactions here. So I'm not sure if I invalidate just the transactions, will that invalidate with this as well? I'm just not entirely sure. So we will see that later.
And inside of here, I'm just gonna add it to do invalidate summary, because we will need to invalidate summary here later. And now let's go ahead inside of the use delete account and let's first of all rename it to use delete transaction, so individual. And inside of here let's first rename this to use delete transaction and we're going to change this to use API.transactions. So we have the proper response type and so we have the proper API call here. So this will be transaction deleted.
We are going to refresh the individual transaction with this ID and we are going to refresh transactions multiple. And we are also going to invalidate summary later on and this will be failed to delete the transaction. Now let's go ahead and let's go inside of use create account. Let's rename it use create transaction. Let's rename the hook use create transaction and let's do the same thing for our API instances to all go to transactions.
So response type, request type and the API call. This is going to say transaction created and is going to invalidate the transactions. And this will say fail to create transaction. There we go. And I'm going to add a to do.
It's going to say invalidate a summary later when it exists. And let's go ahead into the last one here which is use bulk delete accounts. Let's rename it to use bulk delete transaction. Transactions multiple. Let's go ahead and fix the hook name.
And again, we are changing all instances of accounts. So these three into transactions. So response type should be this, request type should be IDs. And what's important is that in here, we are calling the transactions bulk delete. So this is going to say transactions deleted and we are going to invalidate transactions and we are going to say also invalidate summary here and failed to delete transactions there we go perfect But there is one more hook and API endpoint that I want to add here.
So we will be able to add transactions in bulk thanks to the CSV file upload. So because of that upload. So because of that I want to revisit my app API transactions.ts. So we have the get all, we have get individual and in here we have post to create an individual and in here we have post to create an individual and in here we have post to delete multiple. So in between those two or at the bottom, it really doesn't matter, add another post which will say bulk create right here.
And now let's go ahead and let's resolve this bulk create. So first of all we are going to protect it with Clerk middleware. And of course we are doing things in the transactions, right? We add the Clerk middleware and then our z-validator is going to be the following. So it's going to validate the JSON which is going to be a Z.array.
So it's going to be an array of insertTransactionSchema.omit id true. So very similar as our post request as you can see but instead of just accepting a single JSON object this time we accept an array of those objects great so after the validator here let's go ahead and let's open our asynchronous controller and let's go ahead and get the auth using getAuth. Let's get the values using cRequestValid.json. If there is no auth user ID, let's add a question mark here. In that case, we are going to return C.JSON with an error of unauthorized.
It's important to add a status code. So we infer the correct response types here. And now very simply, we get all data. So no need to destructure the individual because we are creating an array, right? So await database.insert into transactions, values, and instead of values, we're gonna add values.map, get the individual value, open an immediate object, use the id to be createId method and spread the individual value inside.
And just add chain.returning inside. And right here at the bottom we're gonna add return c.json and pass in the data there we go so let me just see if I can indent this yes I can indent this one but these ones should not be indented there we go so what this is going to do is it's going to return an array of those created transactions so inside of values we are passing in an array of objects so you can do that natively in SQL or Drizzle ORM in this case. Great! So now that we have this bulk create endpoint let's go ahead and let's add a hook for that. So I'm gonna go ahead and close everything let's go inside of features transactions API and I'm gonna go ahead and copy and paste use delete transactions and this will be use bulk create transactions like this So let's rename this instead of use bulk delete it's going to be use bulk create transactions and instead of bulk delete here we're just going to say bulk create so our response type here will either be an error or data And our request type here is going to be an array of objects which are necessary to create a transaction.
So now we have to modify this as well. It's not going to be bulk delete but bulk create. There we go. So this is how it looks like in one line and instead of transactions deleted this is going to say transactions created and we are going to invalidate the transactions and a to do can stay the same and this will be failed to create transactions. There we go so that is it we successfully added API endpoints, sorry API hooks for all of our API endpoints.
So in the next chapter what we are going to do is we are going to prepare this transactions page right here and we are going to create the form to create a new transaction. So you're gonna be a little bit more complicated because we're gonna have to create a select component, which will be able to, well, search for existing categories and existing accounts, but also we're gonna do it so that the user can easily create a new category or account from that select searchable field. So that's gonna be for the next chapter because it's a module of its own and it's a fairly complicated one. Great, great job.