Skip to content

Commit

Permalink
Feat: Newsletter form and useNewsletter hook (#134)
Browse files Browse the repository at this point in the history
* Add newsletter form

* Add useNewsletter hook

* Update CHANGELOG

* Change component name

* Use newsletter section

* Remove newsletter from footer

* Remove from home page

* Update api version

* Apply changes after reviews
  • Loading branch information
lariciamota authored Jul 22, 2022
1 parent afeb30e commit 2b38bba
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 21 deletions.
34 changes: 33 additions & 1 deletion @generated/graphql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,14 @@ export type FloatQueryOperatorInput = {
nin: InputMaybe<Array<InputMaybe<Scalars['Float']>>>
}

/** Person data input to the newsletter. */
export type IPersonNewsletter = {
/** Person's email. */
email: Scalars['String']
/** Person's name. */
name: Scalars['String']
}

/** Shopping cart input. */
export type IStoreCart = {
/** Order information, including `orderNumber` and `acceptedOffer`. */
Expand Down Expand Up @@ -858,12 +866,18 @@ export type JsonQueryOperatorInput = {
}

export type Mutation = {
/** Subscribes a new person to the newsletter list. */
subscribeToNewsletter: Maybe<PersonNewsletter>
/** Checks for changes between the cart presented in the UI and the cart stored in the ecommerce platform. If changes are detected, it returns the cart stored on the platform. Otherwise, it returns `null`. */
validateCart: Maybe<StoreCart>
/** Updates a web session with the specified values. */
validateSession: Maybe<StoreSession>
}

export type MutationSubscribeToNewsletterArgs = {
data: IPersonNewsletter
}

export type MutationValidateCartArgs = {
cart: IStoreCart
}
Expand Down Expand Up @@ -902,6 +916,12 @@ export type PageInfo = {
totalCount: Scalars['Int']
}

/** Newsletter information. */
export type PersonNewsletter = {
/** Person's ID in the newsletter list. */
id: Scalars['String']
}

export type Query = {
/** Returns information about all collections. */
allCollections: StoreCollectionConnection
Expand Down Expand Up @@ -2363,16 +2383,20 @@ export type StoreCollectionMeta = {
selectedFacets: Array<StoreCollectionFacet>
}

/** Product collection type. Possible values are `Department`, `Category`, `Brand` or `Cluster`. */
/** Product collection type. Possible values are `Department`, `Category`, `Brand`, `Cluster`, `SubCategory` or `Collection`. */
export type StoreCollectionType =
/** Product brand. */
| 'Brand'
/** Second level of product categorization. */
| 'Category'
/** Product cluster. */
| 'Cluster'
/** Product collection. */
| 'Collection'
/** First level of product categorization. */
| 'Department'
/** Third level of product categorization. */
| 'SubCategory'

/** Currency information. */
export type StoreCurrency = {
Expand Down Expand Up @@ -2960,6 +2984,14 @@ export type CartItemFragment = {
}
}

export type SubscribeToNewsletterMutationVariables = Exact<{
data: IPersonNewsletter
}>

export type SubscribeToNewsletterMutation = {
subscribeToNewsletter: { id: string } | null
}

export type BrowserProductQueryQueryVariables = Exact<{
locator: Array<IStoreSelectedFacet> | IStoreSelectedFacet
}>
Expand Down
1 change: 1 addition & 0 deletions @generated/graphql/persisted.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"HomePageQuery": "query HomePageQuery {\n site {\n siteMetadata {\n title\n description\n titleTemplate\n siteUrl\n }\n }\n}\n",
"SearchPageQuery": "query SearchPageQuery {\n site {\n siteMetadata {\n titleTemplate\n title\n description\n }\n }\n}\n",
"ValidateCartMutation": "mutation ValidateCartMutation($cart: IStoreCart!) {\n validateCart(cart: $cart) {\n order {\n orderNumber\n acceptedOffer {\n seller {\n identifier\n }\n quantity\n price\n listPrice\n itemOffered {\n sku\n name\n image {\n url\n alternateName\n }\n brand {\n name\n }\n isVariantOf {\n productGroupID\n name\n }\n gtin\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n }\n }\n messages {\n text\n status\n }\n }\n}\n",
"SubscribeToNewsletter": "mutation SubscribeToNewsletter($data: IPersonNewsletter!) {\n subscribeToNewsletter(data: $data) {\n id\n }\n}\n",
"BrowserProductQuery": "query BrowserProductQuery($locator: [IStoreSelectedFacet!]!) {\n product(locator: $locator) {\n id: productID\n sku\n name\n gtin\n description\n isVariantOf {\n productGroupID\n name\n }\n image {\n url\n alternateName\n }\n brand {\n name\n }\n offers {\n lowPrice\n offers {\n availability\n price\n listPrice\n seller {\n identifier\n }\n }\n }\n breadcrumbList {\n itemListElement {\n item\n name\n position\n }\n }\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n }\n}\n",
"ProductsQuery": "query ProductsQuery($first: Int!, $after: String, $sort: StoreSort!, $term: String!, $selectedFacets: [IStoreSelectedFacet!]!) {\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n edges {\n node {\n id: productID\n slug\n sku\n brand {\n brandName: name\n name\n }\n name\n gtin\n isVariantOf {\n productGroupID\n name\n }\n image {\n url\n alternateName\n }\n offers {\n lowPrice\n offers {\n availability\n price\n listPrice\n quantity\n seller {\n identifier\n }\n }\n }\n }\n }\n }\n }\n}\n",
"SearchSuggestionsQuery": "query SearchSuggestionsQuery($term: String!, $selectedFacets: [IStoreSelectedFacet!]) {\n search(first: 5, term: $term, selectedFacets: $selectedFacets) {\n suggestions {\n terms {\n value\n }\n products {\n id: productID\n slug\n sku\n brand {\n brandName: name\n name\n }\n name\n gtin\n isVariantOf {\n productGroupID\n name\n }\n image {\n url\n alternateName\n }\n offers {\n lowPrice\n offers {\n availability\n price\n listPrice\n quantity\n seller {\n identifier\n }\n }\n }\n }\n }\n }\n}\n",
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Newsletter form and `useNewsletter` hook ([#134](https://github.com/vtex-sites/gatsby.store/pull/134))
- Applies new local tokens to `SearchHistory`, `SearchTop`, `SearchDropdown` and `SearchSuggestions` ([#150](https://github.com/vtex-sites/gatsby.store/pull/150))
- Applies CSS Modules to `Incentives` ([#147](https://github.com/vtex-sites/gatsby.store/pull/147))
- Applies new local tokens to `Footer` ([#147](https://github.com/vtex-sites/gatsby.store/pull/147))
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@envelop/core": "^1.2.0",
"@envelop/parser-cache": "^2.2.0",
"@envelop/validation-cache": "^2.2.0",
"@faststore/api": "^1.10.8",
"@faststore/api": "^1.10.19",
"@faststore/graphql-utils": "^1.10.6",
"@faststore/sdk": "^1.10.6",
"@faststore/ui": "^1.10.7",
Expand Down
47 changes: 32 additions & 15 deletions src/components/sections/Newsletter/Newsletter.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { ComponentPropsWithRef, FormEvent, ReactNode } from 'react'
import { forwardRef, useRef } from 'react'
import { Form, Label, Input, Button } from '@faststore/ui'
import { Form, Label, Input, LoadingButton } from '@faststore/ui'
import { useNewsletter } from 'src/sdk/newsletter/useNewsletter'

import Section from '../Section'

export interface NewsletterProps
extends Omit<ComponentPropsWithRef<'form'>, 'title' | 'onSubmit'> {
Expand All @@ -12,49 +15,63 @@ export interface NewsletterProps
* A subtitle for the section.
*/
subtitle?: ReactNode
/**
* Callback function when submitted.
*/
onSubmit: (value: string) => void
}

const Newsletter = forwardRef<HTMLFormElement, NewsletterProps>(
function Newsletter({ title, subtitle, onSubmit, ...otherProps }, ref) {
function Newsletter({ title, subtitle, ...otherProps }, ref) {
const { subscribeUser, loading } = useNewsletter()
const nameInputRef = useRef<HTMLInputElement>(null)
const emailInputRef = useRef<HTMLInputElement>(null)

const handleSubmit = (event: FormEvent) => {
event.preventDefault()
subscribeUser({
data: {
name: nameInputRef.current?.value ?? '',
email: emailInputRef.current?.value ?? '',
},
})
const formElement = event.currentTarget as HTMLFormElement

if (emailInputRef.current?.value !== '') {
onSubmit(emailInputRef.current?.value ?? '')
}
formElement.reset()
}

return (
<section data-store-newsletter>
<Section data-fs-newsletter>
<Form
data-newsletter-form
data-fs-newsletter-form
ref={ref}
onSubmit={handleSubmit}
{...otherProps}
>
<div data-newsletter-header>
<div data-fs-newsletter-header>
{title}
{Boolean(subtitle) && subtitle}
</div>

<div data-newsletter-controls>
<div data-fs-newsletter-controls>
<Label htmlFor="newsletter-name">Your name</Label>
<Input
id="newsletter-name"
type="text"
name="newsletter-name"
ref={nameInputRef}
required
/>
<Label htmlFor="newsletter-email">Your email</Label>
<Input
id="newsletter-email"
type="email"
name="newsletter-email"
ref={emailInputRef}
required
/>
<Button type="submit">Subscribe</Button>
<LoadingButton type="submit" loading={loading}>
Subscribe
</LoadingButton>
</div>
</Form>
</section>
</Section>
)
}
)
Expand Down
31 changes: 31 additions & 0 deletions src/sdk/newsletter/useNewsletter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { gql } from '@faststore/graphql-utils'

import type {
SubscribeToNewsletterMutation as Mutation,
SubscribeToNewsletterMutationVariables as Variables,
} from '../../../@generated/graphql/index'
import { useLazyQuery } from '../graphql/useLazyQuery'

export const mutation = gql`
mutation SubscribeToNewsletter($data: IPersonNewsletter!) {
subscribeToNewsletter(data: $data) {
id
}
}
`

export const useNewsletter = () => {
const [subscribeUser, { data, error, isValidating: loading }] = useLazyQuery<
Mutation,
Variables
>(mutation, {
data: { name: '', email: '' },
})

return {
subscribeUser,
data,
error,
loading,
}
}
10 changes: 6 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1927,10 +1927,10 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"

"@faststore/api@^1.10.8":
version "1.10.8"
resolved "https://registry.yarnpkg.com/@faststore/api/-/api-1.10.8.tgz#be0d7297e4514e6d328b42cdf722cb6099b2c08b"
integrity sha512-os6ebn8j3N1lVekZLCenDwNJI+CR8JQ04Fz4CimYrQhD461q8Hl7BzfVe5FB+aERzHLBlrUm1OkE5IaCkKD7VA==
"@faststore/api@^1.10.19":
version "1.10.19"
resolved "https://registry.yarnpkg.com/@faststore/api/-/api-1.10.19.tgz#daa99085130e65d5d62b442f8138b29e38914dcb"
integrity sha512-DK6lEU/4MMoEbLgCOU+BB8s82tkpNKp12YaWdwdxmr61hUVOkwUY3Qs3wX27nn2rL2xPgvNu0/MBIdP7GxPziQ==
dependencies:
"@graphql-tools/schema" "^8.2.0"
"@rollup/plugin-graphql" "^1.0.0"
Expand Down Expand Up @@ -21018,8 +21018,10 @@ watchpack@^1.7.4:
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453"
integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==
dependencies:
chokidar "^3.4.1"
graceful-fs "^4.1.2"
neo-async "^2.5.0"
watchpack-chokidar2 "^2.0.1"
optionalDependencies:
chokidar "^3.4.1"
watchpack-chokidar2 "^2.0.1"
Expand Down

1 comment on commit 2b38bba

@vercel
Copy link

@vercel vercel bot commented on 2b38bba Jul 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.