So now that we have our working form picker and our working input and everything is working fine let's go ahead and let's actually render a list of our boards. So inside of your Prisma Studio just make sure that you have a couple of boards here which have all the necessary fields like thumbnail URL, full image URL and some other stuff here. Great! So I'm gonna go back inside of board list component which we have inside of the app folder platform dashboard organization ID components board list right here and let's go ahead and let's import the Database because remember this is a server component so we can go ahead and fetch the actual boards from here and let's also extract the current organization id from auth util which we get from clerk next js which I'm just going to move here to the top and then let's say if we don't have the current organization ID let's go ahead and return redirect from next slash navigation to slash select dash org and I imported the next navigation from here. Great!
So if there is no organization ID present even though this shouldn't happen because our middleware prevents it from happening but keep in mind that this one can be null or undefined so it's just easier to do this check rather than you know checking it every time. And now let's go ahead and write const boards to be await db.board.findMany and since we're using await we also need to turn this board list into an asynchronous function and let's write where? OrganizationId. That's the only criteria we need and let's order by created at descending. Great now that we have that we can go ahead and iterate over those boards.
So let's go ahead and just above the form popper here let's do boards.map get the individual board here and let's go ahead and add a link from next slash link so I just added that input here let me move it to the top and let's go ahead and give it some props. So href is going to be slash board slash individual board ID. Then we're going to have a key which is board ID. So let me just make that the first attribute here. Great then we're gonna have a style which is going to be background image and let's open back ticks to be URL and inside let's go ahead and access the board image thumb URL.
So we save the thumb URL purposely because it takes only a few seconds to load that small image but then later we also save the full image so that we can actually load it when it comes to well loading a board entirely and let's add a class name here which is group relative aspect-video bg-no-repeat video, bg-no-repeat, like that, bg-center, we're also going to have bg-cover and let's also add bg-sky-700 case it's still loading rounded small, H dash full, W dash full padding 2 and let's go ahead and add overflow hidden like that, great and now inside of the link Let's go ahead and let's open a div here, which is actually gonna be a self-closing tag. So a div like this and let's add a class name to it to be absolute in set 0 bg black 30 and group-hover is going to be bg black slash 40 and transition And now let's add a paragraph which is going to render the actual board title and let's give it a class name to be relative font semi bold and text white. There we go. And here we have a list of our boards now and you can see how when we hover we have a nice little darkened effect and when we click on individual one it redirects us to that specific board ID.
Perfect! So what I want to create now is a little loading state. Right now as you can see it's just plain like this. So let's go ahead and let's create an actual loading state for that and then we're gonna wrap the entire thing in suspense so it doesn't block the UI while it's loading. So let's go to the bottom of the board list and write boardList.skeleton to be function skeleton boardList and let's go ahead and return a div with a class name to be grid-cols-2, small-grid-cols-3, large-grid-cols-4 and gap-4 and inside let's render the skeleton component from add-components UI skeleton and let's go ahead and give it a class name of aspect-video h-full w-full and padding of 2 and let's go ahead and just copy this perhaps 8 times like this let's try that out now well actually we don't actually use this skeleton anywhere.
So before we go ahead and do that, let's head back. Make sure you save this in the board list and let's head back inside of page.vsx which renders the board list and Let's go ahead and wrap it inside of suspense from react. So make sure you import suspense. Like this and wrap the board list inside of suspense and go ahead and give it a fallback to be board list.skeleton, which we just created like that and let's see this now so when I refresh there we go it's very fast but for a second You can see how there is a skeleton in place of my boards here. Yeah, especially when we switch between organizations, you can see how they're still loading.
Perfect. So exactly what we wanted to achieve. So we are now officially, Well, regarding UI done with this page right here, we can create new boards. What we'll focus on now is creating this 404 page, which well is going to render the individual board, where we're going to be able to change the title of the board, delete the board, and then we're slowly going to go ahead and implement the drag and drop functionality. And then when we get to that, when we get to specific card and task functionality, that's when we're going to add the activity and then we're going to wrap up both the activity here and also in the individual card.
So we're gonna leave the activity for a bit later and then we're gonna wrap it up all with of course Stripe subscription and limiting the actual boards. Great, great job!