Skip to content

Commit

Permalink
fix custom setup and other things
Browse files Browse the repository at this point in the history
  • Loading branch information
kentcdodds committed Jul 17, 2023
1 parent c1be11d commit c550453
Show file tree
Hide file tree
Showing 34 changed files with 176 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
76 changes: 75 additions & 1 deletion exercises/04.file-upload/01.problem.multi-part/README.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,77 @@
# Multi-part form data

TODO: write this
🧝‍♂️ I've made some adjustments you may want to know about. We now have a new
resource route that's responsible for serving
images: <InlineFile file="app/routes/resources+/images.$imageId.tsx" />.

So now any image can be displayed by its ID via: `/resources/images/:imageId`.
So I updated <InlineFile file="app/routes/users+/$username_+/notes.$noteId.tsx" />
to use this new route to display the images for notes. So that's all ready for
us to start storing images for notes.

Another thing I did to help prepare for your work is I put together a fancy
`ImageChooser` component you can use for the user to have a nicer UX for
selecting an image than the default file input. It's a bit more involved than
you have time for, but feel free to explore how that's implemented if you've got
time. You will be making some changes to it during the workshop.

You'll find it at the bottom
of <InlineFile file="app/routes/users+/$username_+/notes.$noteId_.edit.tsx" line="182" />.
I also updated the loader to load the note's images if it already has images:

<CodeFile
file="app/routes/users+/$username_+/notes.$noteId_.edit.tsx"
range="17-35"
highlight="32"
/>

So you can use that to preload the images for the note if it already has images
when the user goes to edit the note.

As a reminder, you can check the Diff tab and select the previous solution step
vs this problem step to see all the changes I made.

Alright, with that background, I think you're ready to make your adjustments!
Good luck!

👨‍💼 Thanks Kellie! Alright, we need you to make adjustments so we can start
uploading images to the notes page. We'll be making the minimal changes for this
and we'll progressively improve it in the next steps. That means we'll be
ignoring some of the TypeScript stuff (sorry Lily! 🦺😢).

At a high-level, here's what you'll be adjusting:

- Update the `encType` of the form so we can accept file uploads
- Update the `type` on our file upload input so it's a file input
- Properly parse the request in our action so it can handle the file upload
using Remix's memory upload handler
- Render a hidden input for the existing image ID if it does exist so it's
preserved if the user's just wanting to update the alt text.

Here's that example again of how to process the file in your action:

```tsx
import {
unstable_createMemoryUploadHandler as createMemoryUploadHandler,
unstable_parseMultipartFormData as parseMultipartFormData,
} from '@remix-run/node'
export const action = async ({ request }: ActionArgs) => {
const uploadHandler = createMemoryUploadHandler({
maxPartSize: 1024 * 1024 * 5, // 5 MB
})
const formData = await parseMultipartFormData(request, uploadHandler)

const file = formData.get('avatar')

// file is a "File" (https://mdn.io/File) polyfilled for node
// ... etc
}
```

The emoji team (🐨💰🦺💣) will be in there to help guide you through this one.
Enjoy!

- [📜 `input[type=file]`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file)
- [📜 `File`](https://developer.mozilla.org/en-US/docs/Web/API/File)
- [📜 **`unstable_parseMultipartFormData`**](https://remix.run/docs/en/main/utils/parse-multipart-form-data)
- [📜 **`unstable_createMemoryUploadHandler`**](https://remix.run/docs/en/main/utils/unstable-create-memory-upload-handler)
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ function ImageChooser({
}}
// 🐨 add a name of "file" here:
type="file"
accept="image/*"
// 🐨 add accept="image/*" here so users only upload images
/>
</label>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
11 changes: 10 additions & 1 deletion exercises/04.file-upload/01.solution.multi-part/README.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# Multi-part form data

TODO: write this
👨‍💼 Great work! To be honest, we're being a little hand-wavy on the bit around
persisting the data. That's just out of scope for this workshop. It does highly
depend on your application and where you choose to host your images. If you'd
like to see how we're managing it in the app currently (not recommended for
production), check <InlineFile file="app/utils/db.server.ts">`updateNote`</InlineFile>.

We'll get to improving this in the future.

We're missing some nice validation and our types aren't great, let's fix that
next.
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
50 changes: 49 additions & 1 deletion exercises/04.file-upload/02.problem.file-validation/README.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
# File Validation

TODO: write this
🦺 I'm not too pleased with the fact that we're just ignoring TypeScript.
Remember:

<callout-success>
TypeScript isn't making your life **worse**. It's just showing you how **bad
your life already is.**
<br />– [me](https://twitter.com/kentcdodds/status/1540025247134429185)
</callout-success>

Currently, users could upload whatever they want to our server and we don't
validate anything at all, so it could lead to pretty broken experiences.

We've already got Zod setup in this form, we just need to add support for the
`imageId`, `file`, and `altText` fields.

To help you with the Zod schema, you may checkout
[the Conform docs on File Uploads](https://conform.guide/file-upload). Here's
a snippet from that example:

```tsx
const schema = z.object({
profile: z
.instanceof(File)
// When browser constructs a form data from an empty file input, a default file
// entry would be created. we can validate this by checking the filename and size.
.refine(file => file.name !== '' && file.size !== 0, 'Profile is required'),
})
```

In our case, the file is optional since the user may just be updating an
existing file. But we _do_ want to warn the user if they're going to try and
upload a file that's too large, so for our `refine` call, we can just check that
the `file.size` isn't too big.

We'll get to actually _displaying_ errors later on.

<callout-danger>
If you're trying to submit the form and nothing is happening, it could be an
error that's preventing the form from submitting. But you'll not see the
errors until we add those. Until then, you can comment out the `onValidate`
function to prevent client-side validation and check out errors in the network
tab.
</callout-danger>

With that, you should be good to go on this one!

- [📜 Conform File Uploads](https://conform.guide/file-upload)
- [📜 Zod `instanceof`](https://zod.dev/?id=instanceof)
- [📜 Zod `refine`](https://zod.dev/?id=refine)
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
11 changes: 10 additions & 1 deletion exercises/04.file-upload/02.solution.file-validation/README.mdx
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# File Validation

TODO: write this
🦺 I'm just so relieved to have everything typed and validated.

👨‍💼 Great work!

As mentioned, we're not yet displaying errors because we've not wired up Conform
form utilities to our form. We'll be changing the structure a bit in the next
exercise so that's why we're not doing that as part of the exercise.

💯 If you've got some extra time, you can go ahead and wire the form fields up
to `conform` so you can display the errors.
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ export async function updateNote({
}) ?? []

const noteImages = await Promise.all(noteImagePromises)
console.log({ noteImages })
db.note.update({
where: { id: { equals: id } },
data: {
Expand Down
Loading

0 comments on commit c550453

Please sign in to comment.