Skip to content

Commit

Permalink
Merge branch 'main' into docs/change-blockquote-color
Browse files Browse the repository at this point in the history
  • Loading branch information
jtoar authored Apr 1, 2022
2 parents f61751d + c265f9b commit b853920
Show file tree
Hide file tree
Showing 60 changed files with 2,630 additions and 988 deletions.
102 changes: 74 additions & 28 deletions README.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/docs/cookbook/background-worker.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ yarn rw g script faktoryWorker

We'll start by registering a task called `postSignupTask` in our worker:

```jsx title="scripts/faktoryWorker.js"
```javascript title="scripts/faktoryWorker.js"
const { postSignupTask } from '$api/src/lib/tasks'
import { logger } from '$api/src/lib/logger'

Expand Down Expand Up @@ -57,7 +57,7 @@ Set `FAKTORY_URL` in `.env` to where your server's running.
In `postSignupTask`, we may want to perform operations that need to contact external services, such as sending an email.
For this type of work, we typically don't want to hold up the request/response cycle and can perform it in the background:

```jsx title="api/src/lib/tasks.js"
```javascript title="api/src/lib/tasks.js"
export const postSignupTask = async ({ userId, emailPayload }) => {
// Send a welcome email to new user.
// You'll have to have an integration with an email service for this to work.
Expand All @@ -74,7 +74,7 @@ Once we've created our task, we need to call it in the right place.
For this task, it makes sense to call it right after the user has completed their signup.
This is an example of a Service that'll most likely be called via a GraphQL Mutation.

```jsx title="src/services/auth/auth.js"
```javascript title="src/services/auth/auth.js"
const faktory = require('faktory-worker')

export const signUp = async ({ input }) => {
Expand Down
12 changes: 6 additions & 6 deletions docs/docs/cookbook/custom-function.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Time for an interlude within an interlude, because that's how you'll always feel

If you don't know much about CORS, it's something you probably should know some about at some point. CORS stands for Cross Origin Resource Sharing; in a nutshell, by default, browsers aren't allowed to access resources outside their own domain. So, requests from `localhost:8910` can only access resources at `localhost:8910`. Since all your serverless functions are at `localhost:8911`, doing something like

```jsx
```javascript
// the `http://` is important!
const serverTime = await fetch('http://localhost:8911/serverTime')
```
Expand All @@ -66,7 +66,7 @@ We could set the headers for `serverTime` to allow requests from any origin... b

Ok—back to our custom Function. Let's get the current time and return it in the body of our handler:

```jsx {6} title="api/src/functions/serverTime.js"
```javascript {4} title="api/src/functions/serverTime.js"
export const handler = async (event, context) => {
return {
statusCode: 200,
Expand All @@ -81,7 +81,7 @@ export const handler = async (event, context) => {
How about we make sure the response is a JSON object:

```jsx {6-7} title="api/src/functions/serverTime.js"
```javascript {4-5} title="api/src/functions/serverTime.js"
export const handler = async (event, context) => {
return {
statusCode: 200,
Expand All @@ -103,7 +103,7 @@ Since you are most definitely an elite hacker, you probably noticed that our new
Inspecting the `event` argument being sent to `handler` gets us all kinds of juicy details on this request:

```jsx {4} title="api/src/functions/serverTime.js"
```javascript {2} title="api/src/functions/serverTime.js"
export const handler = async (event, context) => {
console.log(event)
return {
Expand Down Expand Up @@ -143,7 +143,7 @@ Take a look in the terminal window where you're running `yarn rw dev` to see the

That first entry, `httpMethod`, is what we want. Let's check the method and return a 404 if it isn't a **GET**:

```jsx {4-6} title="api/src/functions/serverTime.js"
```javascript {2-4} title="api/src/functions/serverTime.js"
export const handler = async (event, context) => {
if (event.httpMethod !== 'GET') {
return { statusCode: 404 }
Expand Down Expand Up @@ -186,7 +186,7 @@ $ curl http://localhost:8911/serverTime

Redwood uses the async/await version of Function handlers, but you can also use the callback version. In that case your Function would look something like:

```jsx {3,5,8,12} title="api/src/functions/serverTime.js"
```javascript {1,3,6,10} title="api/src/functions/serverTime.js"
export const handler = (event, context, callback) => {
if (event.httpMethod !== 'GET') {
callback(null, { statusCode: 404 })
Expand Down
16 changes: 8 additions & 8 deletions docs/docs/cookbook/file-uploads.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ yarn rw dev

We'll create a single model to store our image data:

```graphql title="api/db/schema.prisma"
```javascript title="api/db/schema.prisma"
model Image {
id Int @id @default(autoincrement())
title String
Expand Down Expand Up @@ -81,7 +81,7 @@ yarn workspace web add filestack-react

We want the uploader on our scaffolded form, so let's head over to `ImageForm`, import Filestack's inline picker, and try replacing the **Url** input with it:

```jsx {11,51} title="web/src/components/ImageForm/ImageForm.js"
```jsx {9,49} title="web/src/components/ImageForm/ImageForm.js"
import {
Form,
FormError,
Expand Down Expand Up @@ -165,7 +165,7 @@ But that doesn't help us attach anything to our database record. Let's do that.
Let's see what's going on when an upload completes. The Filestack picker takes an `onSuccess` prop with a function to call when complete:
```jsx {10-12,18} title="web/src/components/ImageForm/ImageForm.js"
```jsx {8-10,16} title="web/src/components/ImageForm/ImageForm.js"
// imports and stuff...

const ImageForm = (props) => {
Expand All @@ -191,7 +191,7 @@ Well lookie here:
`filesUploaded[0].url` seems to be exactly what we need—the public URL to the image that was just uploaded. Excellent! How about we use a little state to track that for us so it's available when we submit our form:
```jsx {12,21,28} title="web/src/components/ImageForm/ImageForm.js"
```jsx {10,19,26} title="web/src/components/ImageForm/ImageForm.js"
import {
Form,
FormError,
Expand Down Expand Up @@ -228,7 +228,7 @@ So we'll use `setState` to store the URL for the image. We default it to the exi
The last thing we need to do is set the value of `url` in the `data` object before it gets passed to the `onSave` handler:
```jsx {4,5} title="web/src/components/ImageForm/ImageForm.js"
```jsx {2,3} title="web/src/components/ImageForm/ImageForm.js"
const onSubmit = (data) => {
const dataWithUrl = Object.assign(data, { url })
props.onSave(dataWithUrl, props?.image?.id)
Expand All @@ -241,7 +241,7 @@ Now try uploading a file and saving the form:
It worked! Next let's update the display here to actually show the image as a thumbnail and make it clickable to see the full version:
```jsx {78-80} title="web/src/components/Images/Images.js"
```jsx {76-78} title="web/src/components/Images/Images.js"
import { useMutation } from '@redwoodjs/web'
import { toast } from '@redwoodjs/web/toast'
import { Link, routes } from '@redwoodjs/router'
Expand Down Expand Up @@ -404,7 +404,7 @@ It'd be nice if, after uploading, you could see the image you uploaded. Likewise
We're already storing the attached image URL in state, so let's use the existence of that state to show the attached image. In fact, let's also hide the uploader and assume you're done (you'll be able to show it again if needed):
```jsx {7,10} title="web/src/components/ImageForm/ImageForm.js"
```jsx {5,8} title="web/src/components/ImageForm/ImageForm.js"
<PickerInline
apikey={process.env.REDWOOD_ENV_FILESTACK_API_KEY}
onSuccess={onFileUpload}
Expand All @@ -421,7 +421,7 @@ Now if you create a new image record, you'll see the picker, and as soon as the
Now let's add the ability to bring back the uploader if you decide you want to change the image. We can do that by clearing the image that's in state:
```jsx {10-20} title="web/src/components/ImageForm/ImageForm.js"
```jsx {8-18} title="web/src/components/ImageForm/ImageForm.js"
<PickerInline
apikey={process.env.REDWOOD_ENV_FILESTACK_API_KEY}
onSuccess={onFileUpload}
Expand Down
28 changes: 14 additions & 14 deletions docs/docs/cookbook/gotrue-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ yarn redwood setup auth goTrue

By specifying `goTrue` as the provider, Redwood automatically added the necessary GoTrue-JS config to our App.js. Let's open up `web/src/App.js` and inspect. You should see:

```jsx {3-4,13-16,20,24} title="web/src/App.js"
```jsx {1-2,11-14,18,22} title="web/src/App.js"
import { AuthProvider } from '@redwoodjs/auth'
import GoTrue from 'gotrue-js'
import { FatalErrorBoundary } from '@redwoodjs/web'
Expand Down Expand Up @@ -74,7 +74,7 @@ export default App

Time to use that API endpoint we copied from the Netlify Identity page. Replace the value of `APIUrl` with your API endpoint. For example:

```jsx {6} title="web/src/App.js"
```jsx {4} title="web/src/App.js"
// imports...

const goTrueClient = new GoTrue({
Expand Down Expand Up @@ -136,7 +136,7 @@ Did I mention it was basic? If you want to add some polish, you might find both

Now that we have a form interface, we're going to want to do something when the user submits it. Let's add an `onSubmit` function to our component and pass it as a prop to our Form component:

```jsx {6-8,13} title="web/src/pages/SignupPage/SignupPage.js"
```jsx {4-6,11} title="web/src/pages/SignupPage/SignupPage.js"
// imports...

const SignupPage = () => {
Expand All @@ -162,7 +162,7 @@ The _something_ we need to do is—surprise!—sign up. To do this, we'll need a

Let's import `useAuth` and destructure `client` from it in our component:

```jsx {4,7} title="web/src/pages/SignupPage/SignupPage.js"
```jsx {2,5} title="web/src/pages/SignupPage/SignupPage.js"
import { Form, TextField, PasswordField, Submit } from '@redwoodjs/forms'
import { useAuth } from '@redwoodjs/auth'

Expand Down Expand Up @@ -190,7 +190,7 @@ export default SignupPage

And now we'll attempt to create a new user in the `onSubmit` function with [`client.signup()`](https://github.com/netlify/gotrue-js/blob/master/README.md#create-a-new-user) by passing in the `email` and `password` values that we've captured from our form:

```jsx {10-13} title="web/src/pages/SignupPage/SignupPage.js"
```jsx {8-11} title="web/src/pages/SignupPage/SignupPage.js"
import { Form, TextField, PasswordField, Submit } from '@redwoodjs/forms'
import { useAuth } from '@redwoodjs/auth'

Expand Down Expand Up @@ -223,7 +223,7 @@ Presently, our sign up will work as is, but simply console-logging the response

Let's display errors to the user if there is one. To do this, we'll set up `React.useState()` to manage our error state and conditionally render the error message if there is one. We'll also want to reset the error state at the beginning of every submission with `setError(null)`:

```jsx {8,11,15,22} title="web/src/pages/SignupPage/SignupPage.js"
```jsx {6,9,13,20} title="web/src/pages/SignupPage/SignupPage.js"
import { Form, TextField, PasswordField, Submit } from '@redwoodjs/forms'
import { useAuth } from '@redwoodjs/auth'

Expand Down Expand Up @@ -265,7 +265,7 @@ yarn redwood generate page Signin

Back in our `SignupPage`, let's import `routes` and `navigate` from [Redwood Router](../router.md#navigate) and use them to redirect on successful sign up:

```jsx {5,15} title="web/src/pages/SignupPage/SignupPage.js"
```jsx {3,13} title="web/src/pages/SignupPage/SignupPage.js"
import { Form, TextField, PasswordField, Submit } from '@redwoodjs/forms'
import { useAuth } from '@redwoodjs/auth'
import { routes, navigate } from '@redwoodjs/router'
Expand Down Expand Up @@ -332,7 +332,7 @@ export default SigninPage

Then we'll need to import `useAuth` from `@redwoodjs/auth` and destructure `logIn` so that we can use it in our `onSubmit` function:

```jsx {4,7} title="web/src/pages/SigninPage/SigninPage.js"
```jsx {2,5} title="web/src/pages/SigninPage/SigninPage.js"
import { Form, TextField, PasswordField, Submit } from '@redwoodjs/forms'
import { useAuth } from '@redwoodjs/auth'

Expand Down Expand Up @@ -363,7 +363,7 @@ export default SigninPage

Now we'll add `logIn` to our `onSubmit` function. This time we'll be passing an object to our function as we're using Redwood Auth's logIn function directly (as opposed to `client`). This object takes an email, password, and a remember boolean. We'll also chain on `then` and `catch` to handle the response:

```jsx {12-16} title="web/src/pages/SigninPage/SigninPage.js"
```jsx {10-14} title="web/src/pages/SigninPage/SigninPage.js"
import { Form, TextField, PasswordField, Submit } from '@redwoodjs/forms'
import { useAuth } from '@redwoodjs/auth'

Expand Down Expand Up @@ -404,7 +404,7 @@ yarn redwood generate page Home /

In our `SigninPage`, import `navigate` and `routes` from [`@redwoodjs/router`](../router.md) and add them to the `then` function:

```jsx {5,14} title="web/src/pages/SigninPage/SigninPage.js"
```jsx {3,12} title="web/src/pages/SigninPage/SigninPage.js"
import { Form, TextField, PasswordField, Submit } from '@redwoodjs/forms'
import { useAuth } from '@redwoodjs/auth'
import { navigate, routes } from '@redwoodjs/router'
Expand Down Expand Up @@ -463,7 +463,7 @@ export default SignoutBtn

Now we can import [`useAuth` from `@redwoodjs/auth`](../authentication.md#api). We'll destructure its `logOut` method and invoke it in the `onClick` function:

```jsx {3,6,9} title="web/src/components/SignoutBtn/SignoutBtn.js"
```jsx {1,4,7} title="web/src/components/SignoutBtn/SignoutBtn.js"
import { useAuth } from '@redwoodjs/auth'

const SignoutBtn = () => {
Expand All @@ -481,7 +481,7 @@ export default SignoutBtn

This works as is, but, because the user may be in a private area of your app when the Sign Out button is clicked, we should make sure we also navigate the user away from this page:

```jsx {4,10} title="web/src/components/SignoutBtn/SignoutBtn.js"
```jsx {2,8} title="web/src/components/SignoutBtn/SignoutBtn.js"
import { useAuth } from '@redwoodjs/auth'
import { navigate, routes } from '@redwoodjs/router'

Expand Down Expand Up @@ -530,7 +530,7 @@ export default Navigation

Let's destructure [`isAuthenticated` from the `useAuth`](../authentication.md#api) API and apply it to some conditionals in the render method:

```jsx {7,10-14} title="web/src/components/Navigation/Navigation.js"
```jsx {5,8-12} title="web/src/components/Navigation/Navigation.js"
import { Link, routes } from '@redwoodjs/router'
import { useAuth } from '@redwoodjs/auth'

Expand All @@ -554,7 +554,7 @@ Because Redwood Auth uses [React's Context API](https://reactjs.org/docs/context

So, now let's import our sign out button and add it, as well as sign in and sign up links, to the appropriate blocks in the conditional:

```jsx {5,11-18} title="web/src/components/Navigation/Navigation.js"
```jsx {3,9-16} title="web/src/components/Navigation/Navigation.js"
import { Link, routes } from '@redwoodjs/router'
import { useAuth } from '@redwoodjs/auth'
import SignoutBtn from 'src/components/SignoutBtn/SignoutBtn'
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/cookbook/mocking-graphql-in-storybook.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
## Mocking a Cell's Query

Locate the file ending with with `.mock.js` in your Cell's folder. This file exports a value named `standard`, which is the mock-data that will be returned for your Cell's `QUERY`.
```jsx {4,5,6,12,13,14} title="UserProfileCell/UserProfileCell.js"
```jsx {3,4,5,11,12,13} title="UserProfileCell/UserProfileCell.js"
export const QUERY = gql`
query UserProfileQuery {
userProfile {
Expand Down Expand Up @@ -55,7 +55,7 @@ export const standard = {
### GraphQL request variables

If you want to dynamically modify mock-data based on a queries variables the `standard` export can also be a function, and the first parameter will be an object containing the variables:
```jsx {2,7} title="UserProfileCell/UserProfileCell.mock.js"
```jsx {1,6} title="UserProfileCell/UserProfileCell.mock.js"
export const standard = (variables) => {
return {
userProfile: {
Expand Down
4 changes: 2 additions & 2 deletions docs/docs/cookbook/pagination.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ So you have a blog, and probably only a few short posts. But as the blog grows b

We'll begin by updating the SDL. To our `Query` type a new query is added to get just a single page of posts. We'll pass in the page we want, and when returning the result we'll also include the total number of posts as that'll be needed when building our pagination component.

```jsx title="api/src/graphql/posts.sdl.js"
```javascript title="api/src/graphql/posts.sdl.js"
export const schema = gql`
# ...
Expand All @@ -32,7 +32,7 @@ export const schema = gql`
You might have noticed that we made the page optional. That's because we want to be able to default to the first page if no page is provided.

Now we need to add a resolver for this new query to our posts service.
```jsx title="api/src/services/posts/posts.js"
```javascript title="api/src/services/posts/posts.js"
const POSTS_PER_PAGE = 5

export const postPage = ({ page = 1 }) => {
Expand Down
Loading

0 comments on commit b853920

Please sign in to comment.