Talk

Speaking · Dec 2024

4 Hours to Save Santa's Workshop

Web Dev Challenge

Abstract

A live, in-person coding challenge. What could you create if you had 30 minutes to plan and 4 hours to build? Aaron Francis, Charlie Gerard, Kent C. Dodds, and Domitrius Clark took on the Web Dev Challenge to find out.

Transcript
00:00

Speaker 1

If you had 30 minutes to plan and four hours to build, what could you create? Today, we're challenging Charlie, Dom, Kent, and Aaron to build an app to help Santa tame the chaos in his workshop, and we're gonna do it live with the Sanity community here in Southern Pacific Brewing in San Francisco.

00:17

Speaker 2

Let's go. Concerned about Charlie.

00:20

Speaker 1

Oh.

00:21

Speaker 2

Damn.

00:22

Speaker 1

Y'all are cooked.

00:23

Speaker 2

Why did I do that? You're just sitting here menacingly laughing. Be helpful like this guy.

00:29

Aaron Francis

I think I'm done.

00:30

Speaker 1

Welcome to the Web Dev Challenge. We've discovered Santa's workshop is in chaos, and your job is to identify the problem, and then you need to build something to fix it. And as part of your build, you need to be using Sanity.

00:53

And to explain Sanity, what it is, and how it works, we're gonna bring up Simeon.

00:57

Speaker 4

Uh, my name's Simeon. I am a principal educator at Sanity. The simplest way to think about Sanity is it's kind of like a headless CMS, right? So we've got a dashboard to create content, and that's the basics of what you'll work with. What makes Sanity different is this thing we call the Content Lake. It's a real-time cloud-hosted data store that's optimized for content. So what's content?

01:17

If you disable CSS and JavaScript on the page, you're left with text and images. All of that's content. None of that should be in your code base. And what makes Sanity special is that this Sanity Studio app doesn't have privileged access to any of your data. So the app that you're going to build today, or the other apps that you might build, they can also access data from the Content Lake, which can respond to real-time events as well.

01:40

The most exciting part that you probably aren't prepared for yet is that you're going to learn a new query language today called Groq. It's very easy. I'll work you through that today. It's kind of like SQL for JSON. You'll learn Sanity, you'll learn Groq, and you'll love both, I'm sure.

01:55

Aaron Francis

Yay.

01:57

Speaker 1

So you all heard Simeon. We've, uh, we know what we're doing. We've got a plan. Everybody's feeling confident?

02:03

Speaker 2

Yeah.

02:05

Speaker 1

You've got 30 minutes to plan your apps, and your time starts right now.

02:21

Aaron Francis

She brought paper. D- where do I get paper? Nobody gave me any paper.

02:25

Speaker 1

You want some paper?

02:25

Aaron Francis

I want some paper. My name is Aaron Francis. I'm a software developer. What I'm going to build is an ELO chess ranking but for toys. So the kids can log in and say, "I like that one, I like that one," and it's gonna rank them mathematically perfectly so I can say, "That's the one you want." I'll be using, uh, the language of our fathers and their fathers before them, which is PHP, and so I'll be using that.

02:48

Feel very confident with that, but the front end is gonna be tough. Concerned about Charlie. Charlie's just, like, quietly confident, and it freaks me out. Camaraderie. Thank you.

02:58

Speaker 5

If you want more.

02:59

Aaron Francis

No, that's okay. I'll work with this little scrap of paper.

03:02

Speaker 5

Hi, my name's Charlie Gerard. I'm a senior research engineer, and on the side, I like to build creative prototypes. I'm planning on building an app that takes a picture of a handwritten letter and then feeds it into an AI to extract the name and the present of the child. I also want to do some kind of, like, 3D and hand gesture stuff at the end. Um, so I think it's just gonna be a lot. I think it's, yeah, having the time to do it always, yeah.

03:26

Speaker 4

It seems like you might have logged in with a different Studio. Oh, okay. So, um, you need to run Sanity init. So did you see that-

03:32

Aaron Francis

Oh

03:32

Speaker 4

... in the README?

03:33

Aaron Francis

No. No, I didn't read the README.

03:34

Speaker 4

Do you not read the documentation?

03:36

Aaron Francis

What? Let's imagine I'm doing, like, a, like, a toy rating system.

03:43

Speaker 4

Mm-hmm.

03:44

Aaron Francis

How- where should I store the ratings? Like, so when somebody says, "I want this one, not that one," should that go back into Sanity or do I put that in-

03:51

Speaker 4

Yeah, definitely. So you-

03:52

Aaron Francis

... a local database?

03:52

Speaker 4

No, so you can write that as a patch back to that Sanity document.

03:56

Aaron Francis

Even if it's not just, like, an increment field? Even if it's a new record? Like, every vote is a new record is what I want.

04:01

Speaker 4

Oh, yeah. If you... Okay, well, if you wanna store-

04:02

Aaron Francis

That's what I want.

04:03

Speaker 4

Yeah, okay. Absolutely. Well, so you could do that, every vote is a new document.

04:06

Aaron Francis

Uh-huh.

04:07

Speaker 4

And you could set that, and you give it a reference-

04:08

Aaron Francis

Uh-huh

04:08

Speaker 4

... so you can bind two documents together with references.

04:11

Aaron Francis

Uh-huh.

04:11

Speaker 4

And you can say that this vote references that toy.

04:13

Aaron Francis

Uh-huh.

04:14

Speaker 4

Um, and then you'd be able to count what are the number of vote references against this toy. And yeah, that's a Groq query that you'll be able to write.

04:21

Aaron Francis

Okay. I don't know what Groq is, but we'll get there.

04:23

Speaker 4

You're gonna find out.

04:24

Aaron Francis

Yeah.

04:28

Speaker 1

Hey, Simeon. Looks like people need access to the Studio.

04:32

Speaker 4

Uh, that's because you didn't read the README.

04:35

Speaker 2

Wait, wait, wait, wait, wait, wait.

04:36

Aaron Francis

I am not alone.

04:37

Speaker 2

I- the re- no, we can't say that when the README is on my screen. No, I-

04:42

Speaker 1

Opening it and reading it are different things.

04:44

Speaker 2

No, no, no. Whoa, whoa, whoa. Whoa, whoa, whoa. Let's take several steps back before we start pointing any fingers.

04:49

Speaker 6

My name's Demetrius Clark. I had talked to Santa personally, and he told me, "Dude, I do not know how I'm going to find out who is naughty and who is nice." How do the kids do it these days? Well, they do it with cards, and they swipe back and forth. So I'm gonna take that idea, and I'm gonna make it easy for Santa to swipe and figure out who's naughty or nice so that they have a list at the end, and it's easy to give out presents. In this instance, I've got Sanity, which handles a lot of the data.

05:10

I don't have to pull in multiple tools for that. I think that would usually be the part that trips you up. It's just gonna be, like, delivering a really fun UI, which I think is going to be the hardest but most productive part of what I do.

05:20

Speaker 2

Hey.

05:20

Aaron Francis

Now all I wanna do is hack.

05:21

Speaker 2

Hey, Simeon. I followed the README, and it worked just fine. Just wanted to let you know.

05:26

Speaker 4

Do you need a few more takes of that or...?

05:27

Speaker 2

Yeah. Can we get all the angles on that?

05:32

Speaker 1

All right, you're about halfway through your planning time. How's everybody feeling?

05:36

Speaker 2

You tell me.

05:39

Aaron Francis

All in my idea.

05:39

Speaker 1

Uh, that looks... That's... Honestly, that's about as far as I usually get on a plan as well.

05:44

Speaker 2

What am I supposed to do with this? This is nothing.

05:47

Aaron Francis

I think I've got my idea. I just needed a backstory for why this app needs to exist, and it, it came up with a great one for it.

05:53

Speaker 1

I love it.

05:53

Speaker 2

Did you change your idea, Kent?

05:55

Aaron Francis

No, no, it's pretty much the same. Um.

05:57

Speaker 2

What's your idea?

05:59

Aaron Francis

I'm not telling you. You should be able to discern it.

06:02

Speaker 1

You should, you should be able to tell me what it is

06:04

Aaron Francis

Don't, don't, don't stand up and try to exert dominance over the rest of us, okay? I know what you're doing. My name is Kent C. Dodds, and I am a web developer. I teach people how to build excellent web experiences. There's chaos in, uh, Santa's workshop because they don't know what toys are going into what boxes. So I'm going to build an app that you can print a QR code and paste it to the box so that people know what's in what box.

06:29

My biggest problem with hackathons is that I get really, uh, into the weeds. The next thing is over-scoping, and I've been very intentional on not over-scoping it. I, I have watched this show before.

06:45

Speaker 1

That's time, y'all.

06:46

Speaker 4

Woo.

06:47

Speaker 1

I have concerns about every one of these plans. Four hours is always so much shorter than it sounds. I am confident they're gonna get through it, just curious to see what that last 30 minutes looks like.

06:57

Speaker 4

I have a little concern about all the projects 'cause they're so ambitious, but I know that these are the most talented developers you could have assembled, so I should have full confidence they can get something really great by the end of the hackathon.

07:07

Speaker 1

Thank you all so much for being here. How are y'all feeling over here?

07:10

Aaron Francis

Woo.

07:10

Speaker 4

Woo.

07:12

Speaker 1

All right. Right now we are gonna get underway. You all have had 30 minutes to plan your ideas. You've got four hours to build your apps, and that four hours starts right now.

07:22

Aaron Francis

Now.

07:22

Speaker 4

Woo.

07:32

Aaron Francis

Just letting the computer program for me here. Copying the template.

07:38

Speaker 1

Oh, you're doing the-

07:38

Aaron Francis

See, two-factor authentication, a full testing framework, database, which I'm not gonna use.

07:46

Speaker 1

Wow, Kent-

07:46

Aaron Francis

Yeah

07:46

Speaker 1

... this sounds great.

07:47

Aaron Francis

Add deployment.

07:48

Speaker 1

What's it called?

07:50

Aaron Francis

This is the Epic Stack.

07:53

Speaker 1

It's between the Epic Stack and then Laravel guy over here.

07:55

Aaron Francis

Laravel, here we go.

07:55

Speaker 1

You're in trouble.

07:56

Aaron Francis

All right. So I've already got, uh, user authentication-

07:59

Speaker 1

Oh, my gosh

07:59

Aaron Francis

... password reset, emails, queues-

08:01

Speaker 1

Who's authenticating into your app?

08:02

Aaron Francis

... background jobs. Haven't written any code yet, but I got it all.

08:08

Speaker 1

What, uh, what stack are you using?

08:09

Aaron Francis

We're using Astro.

08:10

Speaker 1

Nice.

08:11

Aaron Francis

Astro and Sanity, they work beautifully together.

08:13

Speaker 1

They do.

08:14

Aaron Francis

Little Tailwind. Just a little-

08:16

Speaker 1

Just a little-

08:19

Speaker 7

I'm tired already.

08:20

Aaron Francis

Huh?

08:20

Speaker 7

I'm tired already.

08:21

Aaron Francis

Already? We still have three and a half hours to go.

08:26

Speaker 7

Yeah. Well-

08:27

Aaron Francis

Oh, it's 'cause you're reading the NextJS docs.

08:28

Speaker 7

Yeah, I know. I don't wanna do this. Ugh.

08:37

Speaker 1

I feel like everybody's doing a good job. It seems like it's going well.

08:41

Aaron Francis

So I'm connected. I've got data.

08:44

Speaker 4

You've got content.

08:45

Aaron Francis

Content, sorry.

08:46

Speaker 4

No, my apologies.

08:47

Aaron Francis

No, no. Everything is content, Simeon.

08:51

Speaker 4

Well, Sanity's a platform for structured content, so...

08:53

Aaron Francis

That's great. Did y'all get that? Sanity's a, Sanity's... Excuse me. Sanity's a platform for structured content. Did it work? It worked.

09:08

Speaker 7

Look at that. Okay.

09:08

Aaron Francis

Oh, I'm totally gonna lose this competition.

09:13

Speaker 4

Okay. Perfect. So now, um, in your root layout file, we can put that Sanity live component. I just put it at the end of the body tag here.

09:21

Speaker 7

So-

09:22

Speaker 4

So now-

09:22

Speaker 7

Yes

09:22

Speaker 4

... if you publish a change in the studio-

09:24

Speaker 7

Okay

09:24

Speaker 4

... it should automatically update.

09:26

Speaker 7

I'm, I'm, like, stressed. Oh.

09:29

Speaker 4

Oh.

09:30

Aaron Francis

I don't like any of that.

09:33

Speaker 7

That's, that's so cool.

09:34

Speaker 4

It's over. It's over.

09:36

Speaker 7

I took a picture, and I'm gonna wait. It takes a second. And...

09:41

Speaker 4

Oh. Y'all are cooked.

09:45

Aaron Francis

No. Yeah, obviously.

09:51

Speaker 1

What are, what are you working on right now?

09:52

Aaron Francis

Well, as you can see, I've got a white screen. But I got here from this screen.

09:58

Speaker 1

Oh, nice. Okay.

09:58

Aaron Francis

So we're loading in all of the toys. Uh, and the search actually does work. Once you click on print label, it takes you to this screen. Hey, look at that.

10:05

Speaker 1

Wow, that was, um-

10:06

Aaron Francis

So we've- now you should be able to scan that. It'll take you here. Um, so I'm feeling pretty good.

10:11

Speaker 1

It's looking great. What are you doing right now?

10:16

Speaker 8

Yeah. So we've got some seeded data here. We are moving it over into our, uh, our seed that we were given. Uh, and then I'm, you know, just moving that. I have a couple of components created. We're doing some queries to, to snag out what we need and-

10:31

Speaker 1

Yeah

10:31

Speaker 8

... just some, some absolute fun down here.

10:33

Speaker 1

Cool.

10:35

Speaker 7

So I kind of got the basic blocks working, but I wanna make the UI a little bit nicer, and I had, like, a bonus section that I wanted to add if I have time, and it seems like I'm gonna have time. I wanted to add maybe another route where when I'm adding a present, then I might have, like, a 3D present that's falling in the screen. And just doing the animation thing.

10:55

Speaker 1

Ah.

10:55

Speaker 7

So I don't know. I have time, so-

10:57

Speaker 1

Yeah

10:57

Speaker 7

... you know.

10:58

Speaker 1

So much time.

10:59

Speaker 7

Yeah.

10:59

Speaker 1

I'm, I'm blown away by how far you've gotten so fast.

11:04

Aaron Francis

So right now, so what I've done, I can show you here. I've got, um, I'm fetching all the data out of Sanity, but more interestingly, I am running Elo. So, like, the chess thing.

11:18

Speaker 1

Okay.

11:18

Aaron Francis

So I've got all the math working.

11:20

Speaker 1

And so-

11:20

Aaron Francis

I've got all the data fetching working.

11:22

Speaker 1

I, I didn't ask this earlier-

11:23

Aaron Francis

Yeah

11:23

Speaker 1

... but for, for folks like me who don't know what Elo is-

11:26

Aaron Francis

Yeah

11:27

Speaker 1

... it's, you said chess ranking?

11:29

Aaron Francis

So it's a way to generate a ranked list, um, without having to rank the list yourself. So, like, if you go to a kid-

11:36

Speaker 1

Oh, okay

11:36

Aaron Francis

... and you're like, "What are your top three toys?" They're like, "I have no idea." But if you say, "Do you like this toy better or this toy?"

11:42

Speaker 1

Oh.

11:42

Aaron Francis

And you do that a bunch of times-

11:44

Speaker 1

Then you, you-

11:44

Aaron Francis

... it's a head-to-head competition, and it's easy to choose.

11:47

Speaker 1

Oh, okay. I got it.

11:47

Aaron Francis

And then you end up-

11:48

Speaker 1

I got it

11:48

Aaron Francis

... at the end, you end up with a ranked list.

11:50

Speaker 1

Okay.

11:53

Aaron Francis

Hey, Simeon. Is there a way to fetch two objects at once?

11:57

Speaker 4

You could say, um, type is toy and, and, uh, underscore ID, and then we can have, like, then we need to give it an array, which we can give those variables too. So you'd say that as array toy A and toy B, or yeah-

12:11

Aaron Francis

Can I just do that?

12:12

Speaker 4

I... Probably.

12:12

Aaron Francis

We'll call it A and B

12:14

Speaker 4

Yeah, A and B. Yeah, that's good. And then you need to pass in those params. So it's probably the second argument.

12:20

Aaron Francis

Love it.

12:21

Speaker 4

Okay.

12:26

Speaker 9

Did I just see WASM?

12:28

Speaker 10

Yes. But I, I'm not writing... No, I'm not writing WASM.

12:31

Speaker 9

Okay.

12:31

Speaker 10

It's just... No, no, no, that's what I mean. It's just Tensor Flow.js. There's a certain backend and it's-

12:35

Speaker 9

Oh, oh, oh, Tensor... Yeah, I got you.

12:37

Speaker 10

Yeah, yeah.

12:37

Speaker 9

I got you.

12:38

Speaker 10

No, I'm not that. You know, like, like-

12:40

Speaker 9

I was like, geez

12:41

Speaker 10

... not that-

12:41

Speaker 9

You really came to make us all feel bad about ourselves today.

12:52

Aaron Francis

All right, here we go. Let's see it.

12:56

Speaker 10

Ooh.

12:56

Speaker 9

Ooh.

12:57

Speaker 10

I saw an animation. That's cool.

12:59

Aaron Francis

I dig. It's kind of fun.

13:01

Speaker 9

Yeah, I like that. Is that animation stuff all built into Laravel or are you-

13:05

Aaron Francis

That's Vue.

13:06

Speaker 9

Oh, that's Vue.

13:07

Aaron Francis

Yeah.

13:07

Speaker 9

Yeah, nice, nice, nice.

13:07

Aaron Francis

Using the transition group thing.

13:12

Speaker 4

What we need to n- now do is, like, add a projection-

13:15

Speaker 11

Okay

13:15

Speaker 4

... because all you're returning is just the raw data of that document.

13:18

Speaker 11

Yes, which will be-

13:19

Speaker 4

Which is an-

13:19

Speaker 11

References to other things

13:20

Speaker 4

... adds as a reference to an ID.

13:22

Speaker 11

Okay.

13:22

Speaker 4

And that's all it knows. So what, w- you'll need to add a projection on the end. Uh, yes. Like that.

13:28

Speaker 11

Is that it? Okay.

13:29

Speaker 4

That is it. But now you're only getting toys.

13:32

Speaker 11

Okay.

13:32

Speaker 4

So if there's something, if there were other attributes on this document, like were you using the ID as a key?

13:37

Speaker 11

Uh, yes.

13:38

Speaker 4

Okay.

13:38

Speaker 11

Yes.

13:39

Speaker 4

Yeah, then you probably wanna add that on the line above toys.

13:42

Speaker 11

So it would be ID?

13:42

Speaker 4

Yeah.

13:43

Speaker 11

Okay, sweet. So then I come over here to these toys, and I map. There it is.

13:49

Speaker 4

Yeah.

13:49

Speaker 11

There's my name.

13:50

Speaker 4

That's it.

13:51

Speaker 11

Beautiful. Oh, that's so sick.

13:56

Speaker 4

Uh, hey, Charlie. Uh, how are you feeling at the moment?

13:58

Speaker 10

Uh, yeah, I feel like I'm at the point where because there's an hour left, I'm just adding things that I actually didn't want to add right at the beginning. But it's going all right.

14:08

Speaker 4

Hey, Aaron.

14:08

Aaron Francis

Yeah.

14:08

Speaker 4

What are you working on right now?

14:10

Aaron Francis

Uh, web dev challenge.

14:11

Speaker 4

Okay.

14:12

Aaron Francis

Yeah, is that-

14:12

Speaker 4

Tell me about it.

14:13

Aaron Francis

Is that not right? Oh, oh, oh, which specifically?

14:17

Speaker 4

You are doing a challenge.

14:17

Aaron Francis

Which specifically? Yeah, yeah, yeah. Um, okay. So here, here's what we have. I have the toys loading on the screen, and you can vote for which one you want between the two of them. And then the actual rankings update on the right.

14:30

Speaker 4

Oh, wow.

14:30

Aaron Francis

And so I also did a little UI.

14:33

Speaker 4

I like that, the, uh, the red and green stripes.

14:35

Aaron Francis

A little design.

14:36

Speaker 4

Yeah, yeah. It's beautiful.

14:37

Aaron Francis

I'm a designer, I guess.

14:38

Speaker 4

I think this is your next arc.

14:40

Speaker 11

I've kind of pivoted my idea-

14:42

Speaker 4

Mm-hmm

14:42

Speaker 11

... just a little bit, but I wanna expand now that I have some time. So now, um, we're gonna put together boxes for kids, and those boxes will have multiple toys. You can put in the ID of a toy and add it to their box, and that works just fine. When somebody goes in to enter this, they're not gonna just know the IDs off the top of their head, and so we're going to have a combo box right here so it'll auto-complete the different toys that are available.

15:06

Speaker 4

Excellent.

15:06

Speaker 11

So yeah-

15:07

Speaker 4

Good

15:07

Speaker 11

... using ShadCN to make that happen.

15:10

Speaker 4

Tell me, what are you working on right now?

15:12

Aaron Francis

So we have gotten the app's functionality completely working to where we wanted it to.

15:16

Speaker 4

Awesome.

15:17

Aaron Francis

Now we're working on some, like, mutation stretch goals to keep Sanity up to date as we do the actions. I'm feeling great. Now it's just gonna be like how do I add things to make it look cooler so that when people see their apps, they think, "Wow, those are really technically sound, but that guy's app really put in the paint effort."

15:35

Speaker 4

Are you storing those ranks locally?

15:38

Aaron Francis

No.

15:40

Speaker 4

S- you're, you're sending that mutation to Sanity and getting that data back?

15:42

Aaron Francis

I'm sending the score to Sanity and then getting it back, and then I, I do the sorting locally.

15:47

Speaker 4

Yeah, yeah.

15:48

Aaron Francis

Yeah.

15:50

Speaker 11

It-

15:50

Speaker 4

You could have that pre-ordered

15:51

Speaker 11

... your mutation is very fast.

15:52

Speaker 4

Yeah, that's, that's why I'm asking.

15:53

Speaker 11

Are you doing optimistic UI?

15:55

Aaron Francis

You better believe it.

15:56

Speaker 11

Yeah. Yeah.

15:57

Aaron Francis

Oh, PHP dots-

15:58

Speaker 11

So it's got some new tricks

15:59

Aaron Francis

... is local.

15:59

Speaker 11

Yeah, I, I was just about to add optimistic UI. I better add it now.

16:02

Aaron Francis

No, you can't. You can't. You-

16:07

Speaker 9

I mean, you could, you could play with some UI stuff.

16:10

Speaker 10

Um, I don't know if I can.

16:12

Speaker 9

Just keep going. Just keep going.

16:14

Speaker 10

That's the problem. I think I have reached the, the terminus of my skills- ... on the front end here.

16:24

Speaker 4

Can I introduce you to the size class in Tailwind? Try size 32. It'll set width and height.

16:33

Speaker 11

I love that.

16:34

Speaker 4

Eh?

16:36

Aaron Francis

Where is your help at? You're just sitting here-

16:38

Speaker 10

How's it going?

16:38

Aaron Francis

... menacingly laughing behind me.

16:40

Speaker 4

Yeah.

16:40

Aaron Francis

Judging me. Laughing menacingly. Laughing with menace. Why are you doing all these things?

16:46

Speaker 10

I'm-

16:47

Aaron Francis

Be helpful like this guy.

16:48

Speaker 10

I should stop.

16:51

Speaker 11

What's funny is I, I'm actually using a database in mine.

16:55

Aaron Francis

You are?

16:55

Speaker 11

Yeah, that's a caches in a SQLite database.

16:59

Aaron Francis

I'm not even using a database.

17:00

Speaker 11

So that's hilarious to me.

17:01

Aaron Francis

Database guy is using no database and doing optimistic UI. Optimistic UI guy is doing no-

17:07

Speaker 11

It's-

17:07

Aaron Francis

... optimistic UI and using a database.

17:11

Speaker 11

Yeah.

17:11

Speaker 9

All right, y'all. Five minutes.

17:13

Speaker 10

Five minutes.

17:14

Speaker 9

Five minutes left.

17:15

Speaker 11

We don't even need it. I don't need it. Did everybody hear that?

17:18

Speaker 9

What about you, Kent?

17:19

Speaker 11

I, I finished, like, in the first half hour, and now I'm just adding features.

17:24

Speaker 9

When the timer goes off, that's when I'm done.

17:26

Speaker 11

Yes.

17:26

Aaron Francis

Not, not 30 seconds ago, Kent was like, "Man, I messed up by adding caching." "Oh, boy."

17:32

Speaker 11

I think I fixed that.

17:33

Aaron Francis

"Shouldn't have done that."

17:40

Speaker 9

I think I'm done.

17:42

Speaker 4

Three, two, one.

17:45

Speaker 11

Yoo.

17:45

Speaker 10

Woo!

17:50

Speaker 9

If this looks like fun and you wanna get in on the action, we've got a hackathon going right now. Head to this URL here, get the rules, build an app, and submit it by the deadline. I'll see you there. Okay, we are gonna get rolling with the demos. Yeah, William, you go first. All right. Here we go.

18:09

Aaron Francis

The problem with kids is they don't know what they want. And so here's what we've done. The children yearn for mathematical accuracy, and so- What I've done here is I've taken the, uh, dataset from Sanity. What we're gonna do is we're gonna put two toys head-to-head, and then you just simply, as the child, which one you like most. And you do that enough times, and you end up with a perfectly ranked list.

18:33

You'll see on the right side, um, that 1410, this part over here, that's just the score. And so you put two things head-to-head, and we're gonna just do a little bit of voting here, and you'll see the list start to sort itself out. And we finally are starting to arrive on things that I actually want.

18:54

Robot is at the top. So this is a little bit of a chess Elo rating system. So you put the two next to each other. They each have a score. You put them head-to-head. The winner gets some points, the loser loses some points, and you end up with a perfect list. Um, I used Laravel on the back end, Vue.js on the front end, and Inertia.js in the middle.

19:14

So this is the, um, this is the route, it's just route, and then you go to vote. So we have this GROQ query here, where we're pulling out all of the stuff and then passing it into the view. Now, you may notice that this is pretty darn snappy, and that's 'cause we're doing something called optimistic UI, which as a back-end developer, I learned about last week.

19:39

And so- Um, I've implemented it here in the following way. In the vote controller, thanks to Laravel, we have this defer function. And so what we do here is we say, all right, let's calculate the real scores, but let's do it after we send the response back. So we're gonna take it out of the request-response lifecycle, put it in the background so that everything feels super-duper fast.

20:04

We're gonna calculate an optimistic score. So the front end sends us the scores, and we're like, "Yeah, we'll use those for now." And then we return those immediately to the front end so that it looks like it was super-duper fast. And then in the background, we're calculating based on the real scores from our source of truth, so nobody can sneak some scores in.

20:26

You know how kids are. We patch the documents in one request, and then we broadcast an event to the front end. So all of this is happening after the, the response has been sent back. We broadcast an event that goes out to the front end, and then the front end says, "Aha, now I'm going to update." So on the main channel, when the ratings.updated event comes out, we just pass it into the update function, and that updates the scores for real.

20:54

It turns out it's also a really good way if you've just met some new friends, and some of them are picky eaters- You can decide amongst your new friends who is the pickiest eater. And while it is hard to rank our friends, when you put them head-to-head, it makes it a lot easier. So here, this one's obvious.

21:17

Kent. This one's also obvious. Me. And so you just keep going. So we're gonna say Charlie is more picky. I think it's me. Okay, here we go. And there we go. Now we have a perfectly sorted list... Oh, Charlie just went ahead. Perfectly sorted list of your new friends on who is the most picky eater. Thanks to the Elo rating and Sanity and a little bit of Laravel and a little bit of Vue and a little bit of inertia and some optimistic UI.

21:44

Speaker 12

Woo!

21:44

Aaron Francis

Thank you very much.

21:49

Speaker 13

I loved that, um, Aaron put together some really great-looking optimistic UI client-side stuff.

21:56

Aaron Francis

Whenev- whenever Kent says you did a good job on the front end, you take that and you keep it deep inside. This is Santa Codes, and this is where Santa goes to, uh, get an idea of what he has in inventory. We can take a look at the, uh, different toys. We can do a search and, um, that filters down.

22:17

And now we've got our basketball hoop, and then we, we can even print a label, so, so Santa's elves can put that on the box where they're putting all the stuff in. Um, and so yeah, once you scan that, you'll end up on this page. And so this just makes it easier for Santa's elves to keep things organized in the warehouse. And that was my whole app. And then I realized, you know what? I've got like two and a half hours left, so let's go and do things a little bit more interesting.

22:40

And we're gonna get into the children, and they're each gonna get their own box. And I have this filtered down to only the nice kids. So yeah, let's go ahead and dive into Ava Miller. Here we're gonna create a box for her, and now we can filter through these toys. So we'll go dollhouse. Add that item, and then, uh, she probably wants a basketball hoop and all of this stuff.

23:01

Now, once you s- the, um, elves have added the different things to Ava's box, then they can print this label and stick it on the box. And now it's really easy for the elves to get the right box into Santa's sleigh at the right time.

23:15

Speaker 12

Woo.

23:16

Aaron Francis

So that is awesome. That's exciting. Let's take a look at, uh, some of the, the pieces of code in here. So when we add an item to the box, we're using, uh, Sanity's write client. Um, we also have, uh, the remove functionality and then of course, um, just reading stuff. So here's that GROQ magic, and what's really cool about this, um, I used Sanity's, uh, TypeGen support, and so I'm generating these types.

23:41

Anytime I change any of the queries or anything, I run the TypeGen, and now, uh, what I get back from these queries is going to be all type safe and beautiful and awesome. It's really, really quite nice. So here, let's take a look at the, yeah, get box for a child query result. And so yeah, type safe, forward and backward. Awesome. Um, so as far as the, uh, UI piece is concerned, so here's the optimistic UI piece.

24:05

We have our loaders coming from the back end, so all of the Sanity interactions are happening on the server, and then that, that shows up, uh, with data on the front end. And then as the user is making changes, or I should say as the elf is making changes, um, we're going to optimistically take these box toys that are based on what the actual data is, and we're gonna just change them.

24:26

So if we are currently removing an item, we're gonna remove that from the optimistic bo- box toys. If we're adding one, then we're gonna add, um, a kind of a fake one so it can hang out for a second until everything resolves, and then it's exactly what it should be. There you go. That is Santa Codes. Thank you.

24:47

Speaker 6

Uh, I, I finished, and the user experiences were good, so I feel good about it.

24:53

Speaker 14

My buddy Santa, he hit me up, called me direct line, as he does, and he told me, "I don't wanna do any more work. I've given the elves most of my work already. I still have to look through the list of kids." So I said, "Dude, I got you. I'll hook you up with a new app that lets you decide, are these kids naughty or nice?" So first we've got Abigail Baker. Um, her recent deed was she made a get well card for a sick friend.

25:16

What do we think?

25:16

Speaker 2

Nice.

25:17

Speaker 14

Okay. This one didn't help with chores, but they did help bake cookies for the bake sale.

25:24

Speaker 15

Sounds selfish. Naughty.

25:25

Speaker 14

We're going naughty. I like that. And so we're just gonna, we're gonna slide through. There's like 26 kids, so we're not gonna do all of them together, you know what I mean? We'll give a few goods.

25:34

Speaker 15

Why'd you put 26 in the demo?

25:36

Speaker 14

Okay, first of all, he put 26 in the demo. We finish it up. We're all done.

25:42

Speaker 15

Woo-hoo.

25:42

Speaker 14

We're good to go.

25:43

Speaker 2

Nice.

25:44

Speaker 14

Thank you. Um, and so realistically, like, a lot of this is just, like, a lot of React smushed together state code that, like, helps you create all of these animations. Um, I think some of the most impressive stuff, which I'm not gonna go, like, deeply through, uh, I'll have the repo up if you wanna check it out, um, is how do you get the animation of actually doing the slide left to right to look good as you're doing it?

26:05

It's really clunky. It took a lot of me and ChatGPT arguing with each other. Um, and then, uh, yeah, this... So you've got a pretty easy create snowflake. Um, but we had to actually inject the CSS to do the snowflake animations because it was really hard for the DOM to, like, recognize the virtual DOM was trying to do an infinite load of all of the snowflakes. Um, so I called back Santa.

26:28

I showed him the app. He said, "Dude, I do not know how I would get by without you." I thanked him. He thanked me. He sent me an invoice. I got paid more than you guys, definitely. Um, and so thank you very much and, uh, yeah, enjoy the app. Thank you.

26:45

Speaker 2

Woo!

26:45

Speaker 6

First of all, I think that together Astro and Sanity actually is a really good pairing. Um, I think Astro has a lot of tools which make that idea of fast and to the point that Sanity has kind of streamlined.

26:56

Speaker 7

I'm Santa, I've decided. And, uh, the point of my app is that I receive a lot of letters from children, and I don't wanna do manual entry in my CMS, you know, to prepare presents and stuff like that. So I want to be using AI to basically extract the important information from letters that children have sent. So, um, I'm gonna extract first name, last name, and a present for the child, and then magically a present is gonna appear on the screen, and I'm gonna grab

27:27

it, and that's it. Uh, okay, so that's me. And I received a letter, and it says, "Dear Santa, my name is Jason Langston, and I would like a pony. Thanks." So I'm doing this, and I'm gonna click on take a picture. Okay. And that should... It's gonna take a second. Ooh, okay.

27:46

Speaker 2

Woo!

27:46

Speaker 7

And now... Wait, wait, wait, wait. I'm not done. And now there's a pony, and if I just like- No.

27:53

Speaker 2

Give it. Woo!

27:55

Speaker 7

Oh, you didn't hear. I recorded. I recorded a sample of, like, ho, ho, ho. Because I'm... So, you know, this is how far I, I went with this. Let's look at the code. There's a lot going on in there. I used Gemini from Google for the, uh, picture recognition. So it takes a picture, it extracts, uh, text, so you just, you know, a new Google generative AI, you load the model that you want, uh, and you can provide a schema that you would like your, kind of, the data to come

28:25

back as. So you don't have to say, "Please come back," you know, uh, "give me that as JSON and stuff." And you can say the properties that you want your object to return, um, to, to have. So first name, last name, present. And in terms of prompt, uh, this is, this is it. Like, I didn't write much more than that. Like, this is a picture of a letter to Santa. Extract the, extract the first name, last name, and present. And then you just, you know, send a message to your chat or to, uh, the AI model, and you can then parse the response.

28:50

That's the Sanity code, and with the new Sanity page, it updates the UI automatically, and that's when you see the, the block with the children's, uh, details. And then I have my little game. And it's using TensorFlow.js for the hand recognition and React Three Fiber for the 3D. Basically, you can use the pose detection model, detect movement. It's right here. You can estimate the pose that you feed it a video feed that is hidden but that is still displayed on the screen, and you can extract the key points that you want.

29:18

In my case, the right wrist, but there's a lot of others. And I am now very tired. Uh, but yeah, that was it. That's it. That's pretty much it.

29:28

Speaker 2

Woo!

29:30

Speaker 15

I didn't have 3D.

29:32

Speaker 7

I got the AI detection done pretty, actually quite quick. So then I kept adding and adding and adding and it's just, yeah, now I'm just totally done, so yeah.

29:40

Speaker 16

Being together with, like, three of the biggest names to, you know, grace the stage is really cool. What surprised me was having to go against Charli Gerrard, and looking at my app and thinking, "Why?" And looking at her app and thinking, "Wow."

29:54

Speaker 7

We all finished our apps, and they all were so different, using different technologies, and we're all able to, like, finish it in four hours, so that was awesome.

30:01

Speaker 6

I did talk to Simeon a lot, getting his help. Um, but lots of it was just confirming what the AI was generating for me. So I was pretty impressed by that.

30:08

Speaker 15

Anytime I would reach for, like, a, a CMS or something, I think now I'll just do Sanity because it has the dashboard built in, especially for non-technical users to be able to edit that.

30:19

Speaker 14

At the beginning of this, I had some concerns about whether or not they would be able to get these things done, and I was... I couldn't have been more wrong. They were done with their first part of their plan before the halfway point, and then they had a ton of time to start adding stretch goals and, and adding whole new features that they hadn't thought of before they started. I, I'm learning more and more that I'm terrible at estimating.

Details
Date
Dec 2024
Location
Web Dev Challenge
All talks
Speaking
Newsletter

Every week: the best things I've found and what I've been thinking about.