Gifting platforms are how we get goodies in the hands of community members and customers. Bryant needs to figure out how to manage products, build pages to handle the giveaways, and manage fulfillment.
Speaker 0: Alright. Alright. Alright. Welcome back to the next episode of 100 Apps 100 Hours where we rebuild or build some of your favorite apps in 1 hour or less or die trying or publicly fail trying is probably more appropriate. I'm your host, Brian Gillespie, developer advocate at Directus.
Welcome. Super excited to have you. Today, we are going to be building a gifting platform. Oh, Brian, that sounds really exciting. Actually, to me, it is.
So let's dive into the details of this. I've recently gone through at Directus and set up a swag program. So we've got tons of users worldwide that use our software getting, merchandise like branded cups or mugs or t shirts, into the hands of our user base, incredibly difficult challenge when you consider that we've got users in the US, we've got users in Germany, France, Namibia, just every country that you can think of. We've got people that we would like to thank and show appreciation for. Very challenging.
So inter gifting platforms. We are going through the process currently with a company called swag.com. They offer a shopping cart and e commerce experience where you can log in and, basically pick your swag, upload your designs, and place orders that they will then fulfill for you. There's quite a few of these types of companies like Sendoso, I found another one called SwagUp, and this one is Codus Design. It basically a swag platform where you place an order, they manage all the fulfillment and inventory and actually delivering those items to your clients or your customers or your potential leads, potential prospects.
They handle all of that for you. The part that I was very interested in, and I'm not discounting the fulfillment and warehousing and all the other bits and bobs that are included in here. That's probably the really difficult stuff. But, our past ecommerce or past swag solution was a Shopify store. And when you're trying to send somebody a thank you gift, it feels a little weird to have them check out on a Shopify store and enter a coupon code to actually get that get that swag or get that gift that you're trying to send them.
And one of the reasons why I really like these platforms is the ability to send out a thank you page that looks very similar to this. There's there's no checkout. They don't have to enter a credit card or a coupon code. I send them a unique link. They can pick their swag, and we get them to enter in their information like their first name, email, country, and address so we know where to ship it.
It is a great experience for them, great experience for us, win all around. That's what we're gonna be building today. Let's dive in. Just a quick recap of the rules. There's 60 minutes to plan and build, so that's plan and build in 60 minutes no more no less, And aside from that there are new rules.
We'll use whatever we have at our disposal whether that's AI or all sorts of other cheat codes from around the Internet. Let's get started. We're gonna dive in. Alright, so before I build any apps, I usually like to take at least 5 minutes to plan. These planning sessions are always fun because it's hard to test your assumptions to get feedback when you have 5 minutes to plan an app.
But here is my initial functionality that we're gonna build into this app. We're gonna need to manage our products and product options. We will need to, create a giveaway page or several different things that the the companies that I looked at called this, like a redemption page. I think giveaway is probably a good one. Thank you page, create a giveaway, a redemption page.
Place an order, place a request. Not sure it's a order because it's free, but hey, that's what we'll do. User places a request, k, let's say user can place an order request, and then we manage and fulfill those through the app. Alright. So that's the app that we're gonna build.
There are 2 components. There's a back end. There's a single page on the front end. What are we gonna need as far as our data model? What is that gonna look like?
So we'll jump in and let's do, we certainly have products. Oh, I'm not ready to drag arrows yet. We've got our products. What is next? We've got our giveaway page, right?
Giveaway. But then we have customers, you know, we'd probably wanna track that as a separate table or those could just be people. And then we'll have orders and probably some actual order items. So when we look at this, all our products roll up to a giveaway and we this is probably gonna be like a mini to mini relationship because we could have many different products on many different giveaways. When we go to products those are gonna be to the order items, customer orders or items will be orders attached to giveaways.
I I just really like drawing arrows half the time. So as far as the rough data model, this looks pretty good. You know, curious to hear your feedback if if you set up ecommerce before, especially on how you handle like product variants and things like that. But let's dive in and not waste too much more time. Let's actually start building this.
I'm just gonna move this off to the side. What does our setup look like as far as how we're gonna build? I've got a local Nuxt starter app set up. I've got a Directus folder where I've got a Docker Compose file that just simply creates my Directus instance that we're gonna be using on the back end. And then this Nuxt application just has a SDK for Directus already pre configured with a plugin using the the Nuxt plugins and, you know, nothing too fancy.
The only, like, major difference here is there's a composable, view composable included for making the Directus requests, because Nuxt has that nice auto import feature. Alright, so let's log into our Directus instance and start building something right away. Let me look at what I'd use for my password here, just paste that and as we look let me get my data model up in view so we can actually start building. But as we look, this is a blank instance, I'm not doing any kind of crazy cheating here. Let's start building.
So we'll create a new collection for products, we'll track some dates on this, you know, is this a draft product or not? Maybe we don't really need that for this particular instance. Alright. So on our products, what do we have? What are we using?
We've got a name for our products, that's great, that's just a string. We've got a description for our product, We probably have some images for our product. So we've got some images. This is going to be using the relational fields inside Directus. And what's happening behind the scenes here as I'm building these collections and adding fields to it, the Directus API is mirroring this setup inside my Postgres database.
And at the end of this, as soon as I get done building this data model, I'll have a ready to go API that I can then call on my front end to render those products. So we've got name, description, images, we're probably gonna have some options for our products like color and size. A more robust setup here would be to create separate collections for those, you know, a a product options and then maybe a product options values so that that could be dynamic. To streamline this, I think I wanna go with the repeater inside Directus. So this is just a JSON store and we'll call this options.
So our options, we're gonna edit the fields here. The first option is gonna be the name of the option and then that'll be a string. We require a value for that, that'll be an input. It's fine. Let's make it full width and then next let's add values.
So we're gonna get a little meta here and then I am going to embed a repeater within a repeater. Sounds pretty wild. So the field here, let's call it value. And I could probably have like a label and value in case the the value that I wanted to track was different than the label, but this looks pretty okay. We'll hit Save.
We've got name, we've got description, we've got images, you know, if I had something like a SKU we can work on that, but let's keep it simple, right, let's keep moving. What's next? We have our giveaway. So this is gonna be a giveaway page, and if I pull up one, like, the direct to sample, we've basically got a logo, we've got a headline, we've got some description, then we have the products and we have a form. So let's add a table for giveaways.
We'll go in and we'll set a status on the giveaway if this is published or not. Let's go in, we'll create a new field, we'll call it headline. We'll just make that a string. Then we have a description that we could set. So we'll do a description.
Again that will be rich text so we could potentially have, lists or, you know, bold italicized text. And then we want to add our products. Right? So with our products, we're gonna use the relationship features inside Directus, and we're going to use that many to many relationship. Because one giveaway could have many products, and we could use many products on many giveaways on we use one product on many giveaways.
So the let's call this field products. Our related collection is also gonna be products, and we don't want to allow duplicates. We do wanna show a link to the item so we can go back to that product. And I'm just gonna open this in advanced mode. So behind the scenes, what's happening when we use this many to many relationship?
Inside the Directus or inside our Postgres database, Directus is creating a junction table called giveaways_products. Now I could adjust what that table is called, and even the foreign keys that it's setting up inside that junction collection, what it's naming those. But I'm just gonna go with autofill in this case. If I want to add the reverse relationship back on the products, so if I wanna reference those giveaways on the products themselves, I can do that here as well. And then maybe we add a sort field just to control the order.
Maybe I want the shirt to show up first before the other items. Great. Directus is gonna tell me what all it's going to create inside my database, and now we've got our products. What else do we need? Do we need anything else here?
The form, maybe we hard code that. Great. So if we look what else? We've got a customer, we've got orders, and order items. Alright.
So let's go ahead and set those up as well. So we got a customer, actually let's just call it persons, people. Naming stuff is always the hardest thing. This may not be a customer. Right?
So let's just go with the more semantic name and call it people. So people have a first name, they have a last name, they have an email address, and are we what else are we capturing? Capturing an address for those people. I'm assuming that could be on the order itself. Let's just roll with this.
Right? First name, last name. Maybe we'll capture the address on the order. We could store it here as well, but we'll keep it simple. So we've got then we have an order and the orders are going to what?
What are we gonna have on the order? The order is going to have a customer or a person, where we who's the person attached to that order, that's gonna be a many to one relationship. Alright. So we got the people, person, people, are already regretting this decision. No turning back now.
Right? And then on the reverse side of that, on our people, we'll show the orders. People orders within the data model. Great. Alright.
So the person we have, an address, let's just store that as JSON data for now. So we'll do an address and what else? We have a status is approved, maybe. This is approved, so we want approval before we ship all of these out. Let's add that to the top.
And then last but not least, we want to create the actual items involved with this specific order. So we've got an order items table or you could call it orders items. Again, we get into splitting hairs here. What else do we need? We probably do need a sort for those blah blah blah.
Alright, so we got our order, we got our order items. The items are gonna have a link back to the product. So we've got a related collection is gonna be the products. So when we put those items in the cart, the order item will have a product, so that'll be a relationship and then let's just have a JSON field to store our product options. Maybe we call it item options just to keep them separated.
Good. And then there is a 1 or many to 1 relationship. So there are many items to one order, back to that order. So we've got the order, the related collection is orders. Tell me I didn't.
I did, didn't I? So this is a boo boo. I've got orders here. It should be or I've got order should be orders. That should be a a fun little thing to work around.
Now, I could go into the database itself and edit that if I wanted to, but, no worries. We'll just roll with what we got. There's an order. It's a order. Sometimes you goof up.
What do you do? You keep rolling. Alright. So we've got our data model. Right?
Looks great. Let's go in and maybe add a giveaway. And we can just duplicate this one, right? Directus Swag. Still learning Arc.
I like it as a browser. Yeah. If anybody out there is a Arc expert, maybe you could give me a couple lessons like a tutorial session or something. Alright, so we got our headline, we've got a description. Let's add a product, we don't have any products at this point, so let's create a product.
We've got the Directus, let's let's call it the Bunny Tumbler 20 ounce, Great. This is the most amazing tumbler ever. Great. Now we want to add some images to this. So, I can actually import images from a URL inside Directus, which is super nice, especially for speed runs like this.
I just click upload a file, click the little link that will import our file. Looks great. For our options, we've got color and for the value, we've only got one. It's just white. We're gonna offer that in white.
Great. Okay. Let's go in and add one more product. We've got our Directus logo tee. Kinda sounded like goatee, didn't it?
This is the softest t shirt you'll ever wear, and again, we'll just go in and let's copy the image address and you can see we've got a couple options here. We've got extra small through 2 x, so we'll add those in there as well. Just upload our file. Great. For our options, we've got color, which is a dark heather.
I believe I should know, I'm the one who ordered this stuff. And then let's add another option for what size. Alright. So we got extra small, we got small, we got medium. It'd be really handy if we could just do this in line, wouldn't it?
I'm sure there's a way. Where there's a will, there's a way. Alright. So we've got some extra small through 2 x. We've got our products.
We've added them to a giveaway. Let's go ahead and publish this giveaway and hit save. Great. So we've got our giveaway, and let me just prove it to you. Let's open up Directus.
Alright. So this is our actual database here. We can see we've got order. We've got some directus tables that directus has created for us, and then we have giveaways. So there's our data.
Directus prefixes all the metadata tables that it so it keeps the SQL database pure. That way, you know, you're not locked in or anything like that if you decide to migrate away. Very nice. Very nice. So now let's actually take a look at our giveaway.
Right? How do we fetch this on the front end? And Directus gives us these REST APIs out of the gate. So if we go to Directus URL, which is local host 805 5 items giveaways, we get no permissions. So I have to go back and by default, Directus controls locks down all of my data.
It wants us to be secure. So we've got 2 initial roles in an account. We've got a public role, which controls what data is accessible without authentication. And then we have the administrator role, which has unrestricted access. Now if I was gonna put this behind a login, I would probably do something like creating a user role that didn't have access or didn't have admin access, but they would log in on our front end.
In this case, I'm just going to use the public role. We are going to allow people to see the giveaways, we're gonna allow them to view the giveaways, they can create orders and order items, they'll need to be able to create people, and we could also have, like, a server token, where we're doing some of this on the the server side as well. But we're not super concerned with security on this one because we've only got 40 minutes left to build this app. So we will allow access to see the products, see all the product files, and then we're going to go into the Directus Files under the System Collections and we're gonna allow that. So now if I go back, I open this up go to 8055/items/ giveaways.
Boom. There's our giveaway data. Looks great. And we don't see any of our products. I'm gonna show you one of my favorite features about Directus Now and that I'm using the REST APIs.
It also generates GraphQL APIs for you, but this is great. This is one of the things that I love. I could go in and tell it specifically what fields I want using the REST API, and I can even fetch so I'll just do products dot wildcard there. I could even go in and fetch products underscore ID the related data in a single call. So now you can see I've got our giveaway page data up here.
I've got our products data here with all of our options and things like that, and I've only had to make a single call. Amazing. But we're gonna run out of time if we don't start building an app. So we've got our Nuxt app running at local host 3,000. Let's open this up and start trying to build something.
Cool. So we'll go in to our pages, Let's create a new folder. Giveaways. Okay. Looks like I already did that.
Not sure why I cheated a little bit there. But, we will do giveaways slash ID. So we use brackets here to set up a dynamic route inside Nuxt. We'll just do a basic component here, and now I just want to fetch that giveaway data so we can render it. Now typically, if I was using server side rendering or something like that, I would probably want to use the Nuxt async data calls.
It's got a nice use async data as the composable that has a lot of nice little stuff built in, but I'm not super concerned with that here and honestly, this is gonna be a private link. So what we're gonna do is just call the giveaway. We're gonna go giveaway equals await use directus, that's my composable that wraps the API or, I'm sorry, the SDK. I'm gonna do read item, that's the giveaway syntax or the, I'm sorry, the SDK syntax, the giveaway syntax. We don't even know what that is.
And then I need to pass it an item. So before I do that I'm gonna use route from Nuxt and then I can do something like this where we have route dot params dot ID And then the 3rd argument here is just an object with options. So in this case, I'm just gonna use fields for right now and show you what that looks like. Now on the front end, typically what I'll do a lot is just render that out so I could see what we're working with. Now how do I actually navigate to this?
Inside Directus, I could go into my data model for our giveaway page, and maybe I wanna set up a button where I can actually get to this specific item. So we'll just create a new button, we'll say view giveaway, And, you know, if this is live, obviously, you're gonna change the URL. But this is gonna be my Nuxt URL, HTTP / localhost3000/giveaways/id, and then I can click this plus button to add the dynamic variables from the ID of this item. If you added the raw value, you can see we're just using mustache syntax here. We'll hit save, save, you give away.
Looks good. We go to the giveaway. Now I've got this button I could click that I view giveaway and boom, should be showing me that, but instead I'm getting forbidden. Why are we getting forbidden? If I look, I could see that I left off the s.
I'm assuming that's probably part of it. So let's just refresh, and boom. Now I can see our giveaway. So here's our actual data for this specific giveaway. It's great.
So let's style this bad boy a bit. Trying to remember what I've actually got in here as far as like the layouts. So the Nuxt layout directory is super handy, this is the default layout, looks good. What are let's just copy what we've got on our index page here, and we'll go to giveaways. Alright.
So I don't even know that we wanna flex all of this, do we? Let's give it a purple background, so we'll do pgprimary500 with full height full screen. What do we got? Okay. There we go.
Alright. And then we'll give it a bit of padding. Now we'll do like a white background. I think that's kind of similar to what we've got here. Yeah.
We got some funky business going on there, but we got PG white. Yeah, p 8 and then we've got, okay. Thank you GitHub Copilot for the assist. We got the giveaway dot title, giveaway dot description, that's not quite gonna cut it. So we've got the div here, That's actually HTML that we're getting back, so let's do the pros class in tailwind.
There we go. GitHub Copilot is getting a lot better these days. Is it still is it totally there? I don't think so. Okay.
So we appreciate you big time. So as a thank you, please select your color and reset. Maybe this is text center, I wanna center that up. What do we have here? Bgymaxwith3xlmxauto.
We'll get that in the middle of the page. Why is our h one not rendering? Right? This should be a big bold font. It's not rendering, and if I actually took the time to figure out my types, it would be because that's not the actual key.
It is headline. Alright. So we've got our direct to swag headline. Let's center that up as well. Cool.
Alright. Let's add in our products. So if we open up our Vue dev tools, we go to ID, and I just look at the data that this actual component has, you can see we still have to fetch those products. So what I could do is come into the field section, we'll go to products, We will within that, we're gonna fetch the product underscore ID, and we'll get all the root level fields for that. Let's see what that looks like.
Products. Why are you not giving me what I want? Of course we can always do this as well. Give away. Products is not coming through.
Do we have permissions enabled for those products? Let's take a look. Giveaway products, people products. Looks like we've got read permissions set up for all of that. What am I doing wrong?
Products. Products. ID. Is that it? Where are you?
Okay. There we go. In my haystack, fat fingered, forgot to put an s in here. My wife makes a likes to make fun of my sausage fingers anyway. So alright.
So now we got our products. We'll render these products out. V for product and giveaway dot products. Just show the product. Alright.
So there's the individual products. Again, part of the rules are there are no rules, so let's hop into Tailwind UI. Again, one of my favorite tools. Just a nice library of components that they've already got kind of set up for use cases such as this. Looks like we could make use of this particular one.
Maybe we don't want it served in a modal window though, so we just grab let's grab everything inside the dialog panel. And I'm not sure how the outcome is gonna go here. This is probably gonna break some stuff. Okay. So you can see we've got some products here.
Nothing is actually working correctly because we don't have things like selected size, let's actually just skip this out and we'll bounce into a component. So let's call this the product card, we've got a v comp ts, got my little snippets set up and we'll just copy and paste that in there. So that's our templates, what do they have for the script section of this? Looks like they have selected color, and they've got some headless view. Luckily my Nox starter already has those set up and then they have a product.
So I'll just copy this stuff down. Do we get something on this end? We're getting somewhere. Looking good, except none of this is actually rendering out. That's okay though.
We're gonna sort through that. Right? So we don't need the reviews. We'll just chop those. Let's get this down to bare bones.
Right? The color picker, so we need the size picker. Add to bag, we're probably not gonna need that. View full details, we're not gonna need that, but this is not updating, so I need to actually go in and just swap this out. Product card, b 4 product card.
And then we'll probably end up doing something like this where we have key equals product dot ID. We probably wanna fetch that ID here as well. So do that. Is that right? No.
We're gonna put it here. ID. Alright. So now we're rendering a product card. How we doing on time?
We got 27 minutes left. We are over halfway here. We still gotta be able to submit this form. And then we also are gonna want to pass it, so our product is gonna be product dot products underscore ID. Alright.
So we're not doing anything here now because I'm just using the default setup from Tailwind, from our Tailwind UI components. Where's that size guide coming at from as well? Let's get rid of that. Alright. So we just want the basic details, right?
We're going to define some props, so we'll go prod const props equals define props. Product type is an object. Again, normally I would type this out with an interface or something like that inside using typescript, so we've got that, but, yeah, whatever. Alright. That should break this particular item.
If I refresh, I'm probably gonna get a whole bunch of stuff going on. Got a product. Oh, let me just clear this out because now we no longer have product there. Okay. So we got the bunny tumbler, we've got some colors, we've got some stuff going on.
Is this open and closed? We don't even need that. Alright. So this particular NUC starter and I think I'm gonna have to make this available online just in case anybody wants to look it up and decide if I was using steroids or not, but we'll do product dot images dot 0. Let's see where where that gets us.
Not very far. Alright. So a Nuxt Image is already set up on this particular product or I'm sorry, this particular starter. Let me reload the page here and see what's happening. Alright.
So we've got our products. We're passing that product down to the product card. And what are we actually getting for the images? We're just getting, not getting anything for the images. So, I could go back up to our giveaway.
And now let's drill into our images, if I could stop making typos. Images. Boom. Let's see what we got now. Images and array of objects.
At least now we have a direct us files ID that we can use to access that image. I would probably, you know, if you wanted to get, like, the title description, the alt text, stuff like that, we could drill in even further like this where we have the directus_files_id, and we get the ID, we get the title, get the description. Now let's look at what we've got. We just keep getting further and further into nesting. But, hey, super helpful anyway.
Alright. So now we're getting that if we go to our product card, maybe we just use like a computer prop here. Constant image equals computed and then we'll do return product dot no. We're gonna do props dot product dot images dotzero.directusfiles.id dotid. Alright.
And then here inside our Nuxt image I can just do this where we say image. Clear that alt text for now. Actually we could use the title. Right? So we have let's change that we're returning the actual object instead of the ID We'll do image dot ID, and then the alt text could be image dot title or description.
Great. Same result. We've got our colors. We're at what? 22 minutes, does that need to be overflow hidden?
Where's that coming from? That coming from our I think this was set up for like a, like an application instead of a scrolling page. Bg primary and hide screen, hide full. Yeah. Okay.
Let's not stress over that for the moment. We've got bigger fish to fry. So, we've got our images, we've got our name, let's get our product description into this, product name, product price, the product description is gonna be again vhtml. So we'll just use the Tailwind Class Pros vhtmlproduct.description. Close that.
Let's see what we got. This is the most amazing tumbler ever. There we go. Alright. So how do we get the size and and, like, our different options to display?
Alright. If we look at our product card here, we've got our different options, for the tumbler there's just one option. So we are going to actually, do we need I don't think we need both of these. Right? We will just loop through and create each of those based on the individual options.
So we've got a radio group, and this is the color. Let's just call it the options picker, and we get a v four product, let's call it option. Options. Yeah. That's fine.
And product dot options, then the key is gonna be options.name. Okay. And then here we'll say options dot name, color, selected color, This will probably be something like selected options and that'll be a ref and object. We can do it either way. Let's see what we got.
V model selected. Options and then we'll use the option dot name. We use the key for that. Choose a color, we don't really need that. In product dot colors, in v for value in no, let's do option in options dot options, maybe we call it option, option dot name, Option dot name, selected option, option dot options, Option choice.
Option value. Naming surface fun. Right? Option value dot value. Okay.
And then the value is what? Optionvalue.value.optionvalue.value. With the color dot selected color Not sure what that's doing there. Let's reload and see what's broken. So at least we're looping through these.
Color dot name. Option dot name. Color.bgcolor. Why are these not actually displaying? Radio group, what are we passing into you?
We are running out of time. V4 and product options. So we got a radio group. Let's just omit that. Missing something somewhere.
Product card, let's look at we got our options, product dot options dot name option in options. So the option dot name and option dot values is what we need to loop over. Boom, boom, boom, And looks like I copied the wrong one. So we would probably be showing the values here if I go back to, let's copy this actual radio group option here. What's the difference?
Div class. Just copy and paste this inside their size and stock. Don't need it. This is gonna be the option value dot value. This is gonna give us what we want.
Oh, hey. Look at this. Now we're getting somewhere. Right? Looking beautiful.
Not exactly beautiful, but definitely better than what we had. Right? So now let's take a look at our product card. If we look at our product, selected options dot ref, why is our ref not showing for those? Let me just refresh.
The props, there's our setup, the selected options, this is for the first one, the color is white. Okay. Now if I select the other ones, we check the product card for that one. Where are you? Mister product card.
Selected options are color, dark heather. Looks like we could probably work with this. Right? Now, yeah, we can get carried away here and do like a composable or something like that for our form. Let's just do like a watch and if we were gonna watch what selected options selected options dot, What is the actual watch syntax?
Deep true. No. What is the view watch syntax? Alright. With the composition API, what are we looking for?
We've got a function. So we're gonna watch selected options. Okay. And then we've got the functions. So we got the value, console log, maybe we want to omit that, so we'll pass that up, const emits equals define emit And let's just omit, updated.
Sounds great. Alright. Selected options, we are going to omit. Updated. We will value true.
Okay. Alright. So if we go back to our ID here, let's add a handler for this. Maybe we just do our order here that will be reactive. Okay, and then we've got our order products, we've got the order, what do we have?
A customer? No. It was the person, is what we called it. Alright. That person has a first name, last name, email, and then we have an address.
Great. Alright. So now we've got an order. Cost order equals react. What's the problem with this?
Alright. Great. So now we'll probably need a handler. So let's do a function to handle that emit. So we'll do update cart or update products, products order dot products okay and then when update update products.
Cool. Alright. So let's verify and see what's happening now. So I'll just refresh my page. Unable to fetch.
Oh, what am I doing wrong? Hydration completed but contains a mismatch. What what are we doing wrong here? This is always fun. V if or if we just wrap this really quickly.
Giveaway. Failed to fetch dynamically imported module. I understand. Active from you. So what's going on?
Dying on the vine here. I probably should have been using the, Nuxt Async data all along, We could probably get around this maybe just by using turning SSR off for now, but obviously, not the best solution. Does not have provided a named export called select. What is this? Is this in the product card?
Oh, I don't know why we imported that. How did that get imported? Okay. So it probably wasn't, any issue with the SSR there but, oh well. Alright.
So we're back on our giveaway dot ID. Let's refresh just to make sure we've got everything. Where is our where's our app at? Okay. So we look for our ID.
Now we've got our order object and hopefully, this should be updating, but it's not. Emit updated. That could be why. I actually have to spell it correctly. So we refresh, try again.
If we look at our products, are they updating? They're still not updating. Wonder why that is. So console dot log, good old console dot log products section. Okay.
Products. Okay. Okay. So what do we actually want to do here? This will be we actually need to pass the product ID, don't we?
So updated. Let's do this where we have an event. We want to pass the product ID and the event. Alright. Update products.
This will be what? Clock is ticking. Let's cheat a little bit. Update the porter products array with the selected product. Let's see what GitHub Copilot comes up with really quickly.
It will look through the array, find the index for the item. Okay. Nobody said it was, was easy. Right? So now we've got our products, we've got our ID, we've got the options for the product.
What do we want to, It's actually the product. Right? What is that gonna be inside the database? Let's just take a look at it inside our data model. We got the order, we got a person, Did we not add that reverse?
We didn't add that reverse, so we we're gonna need to add that really quickly. Many to 1, 1 to many, boom boom. Products. Oh, actually, that's gonna be our items. Alright?
It's gonna be the items on the order. Order items, order. Okay. So that's actually gonna change. That'll be our items.
And then our order item itself has the item options, so that'll be item options. Item options equals event, and then the product. Order products dot index item options. We'll just see if this goes according to plan. Okay.
Blah blah blah. We take a look, we've got our giveaway page. What am I missing? Order dot, oh, order dot products dot push. Forgot to update this.
So this will actually be order dot items, order dot items. Okay. So now we've got our items for the order. There's our product, 123. Shouldn't have 3 items, should it?
Maybe that was a mistake. Running into snags everywhere. Lots of fun. Alright, so how do we actually submit this? We still don't have our form either, do we?
Let's build a form. So a form. And actually, I think there is the Nuxt UI component that is built into this thing. So let's just do a form. What are those?
A u input, u form group I think is the right one. Label equals first name, V model equals order dot first name. Oh. That's gonna be you and put the model order first name. Let's see what we get.
Okay, now we've got a form, Let's actually wrap that just a little bit. Max width 3 x l. Actually, let's just move it up inside that. Why why are we doing that? There we go.
Alright, so we've now we've got our form inside here. Bgwhite, shadow. Okay, we got our first name. What do we have? We got a last name, got an email, street, city, GitHub Copilot for the win on this one, And zip.
Alright. That's not looking very pretty, so let's actually set these on a grid. Grid calls 2. Alright. This will be class grid callspan 2.
And give it some gap, gap 2, let's say 6, right? Too much, gap 4. We'll give the form itself some space in between and then we just need a button, submit. Let's make it block. Okay.
Class equals call spin 2. Alright. So big giant form, now we need to submit the order, submit order, await, direct us, use orders, order, giveaway dot ID, create item, that looks correct. Let's wrap this in a try catch error console dot error. Alright.
Time is a ticking. Let's see, we got 43 seconds. Let's see if we can actually get this done. Brian Gillespie, email bryantat directus.io. 123 Main Street, Bluefield, West Virginia.
Submit. Oh, duh. Dummy. Come on now. Submit dot prevent.
Oh, no. He's typo. Submit dot prevent. Submit order. One second.
We hit the timer here right at the very end, just as we were getting really good. I just wanna submit this out and see if it's actually gonna work. Test city, 1232222. Submit. Did we get an error?
Post local items orders equals forbidden. So I'm getting that error because there are permission settings that we didn't control order items. We forgot to set that up. But now if we were to go back and just try this again, orders forbidden. Yeah.
So, something in the way that I'm passing the data here, don't have permissions to access this. It is probably something to do with the person data that I did not get updated. And it's actually what? State Street Zip. This is the this is the main issue why you shouldn't trust AI.
In our hurry, this actually should have been order dot address dot street dot city dot state, all of that. Didn't even pick it up. Hopefully, you're not coding against the clock like I am, but that's one of the the issues there. Test, test, test, test, submit. Still getting some issues.
So, we tried our best. I still think this looks pretty good. And with another 20 minutes or so, 10 minutes or so, we could have completed this out where it would actually submit the order to Directus. But I hope this is a good example of just how quickly you can build apps with Directus, and a a front end framework like Nuxt. Directus gives you a lot out of the box, which makes speed runs like this possible.
This was a lot of fun. I don't think that I'm gonna be replacing swag.com anytime soon, but, nevertheless, if you had different needs or you wanted your own customized platform, you could quickly and easily build it with Directus and have something that was specific to your company. These platforms like swag.com and others are obviously, they have a lot going on on the fulfillment side. But with Directus you could build custom ecommerce like this, custom experiences for people rapidly. So that is it for this episode of 100 apps 100 hours.
Thanks for sticking it out with me and I hope you'll tune in for the next episode. Ciao.