[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/components/Collapsible.tsx from the menu VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, {
  useState,
  useRef,
  useEffect,
  useContext,
  FunctionComponent,
  useMemo,
} from 'react'

const TRANSITION_DELAY = 250

function isFunction(value: any): value is (...rest: any) => any {
  return typeof value === 'function'
}

interface Props {
  open: boolean
}

interface CollapsibleContextValue {
  updateHeight?: (height: number) => void
}

const CollapsibleContext = React.createContext<CollapsibleContextValue>({})

const Collapsible: FunctionComponent<Props> = ({ children, open }) => {
  const { updateHeight: updateParentHeight } = useContext(CollapsibleContext)

  const [height, setHeight] = useState(0)

  const contextValue = useMemo(
    () => ({
      updateHeight: (heightDelta: number) => {
        setHeight(height + heightDelta)
        if (isFunction(updateParentHeight)) {
          updateParentHeight(heightDelta)
        }
      },
    }),
    [updateParentHeight, height]
  )

  return (
    <CollapsibleContext.Provider value={contextValue}>
      <CollapsibleContainer open={open} height={height}>
        {children}
      </CollapsibleContainer>
    </CollapsibleContext.Provider>
  )
}

interface ContainerProps {
  open: boolean
  height: number
}

const CollapsibleContainer: FunctionComponent<ContainerProps> = ({
  children,
  open,
  height,
}) => {
  const { updateHeight } = useContext(CollapsibleContext)

  const container = useRef<HTMLDivElement>(null)

  useEffect(() => {
    /** Calculates the content size on the next browser render tick,
     * because the content might not exist right at the time of
     * changing the open prop
     */
    requestAnimationFrame(() => {
      const element = container.current

      /** The second verification here prevents it from trying to close
       * the menu on initialization (because `open` inits as `false`)
       */
      if (!element || (!open && height === 0)) {
        return
      }

      const initialHeight = element.offsetHeight
      const initialMaxHeight = element.style.maxHeight

      element.style.height = 'auto'
      element.style.maxHeight = 'none'

      const childrenHeight = element.offsetHeight

      element.style.height = `${initialHeight}px`
      element.style.maxHeight = initialMaxHeight

      /** Runs `getBoundingClientRect` to trigger a layout event
       *  in order to make the transition to the new height work.
       */
      element.getBoundingClientRect()

      if (isFunction(updateHeight)) {
        updateHeight(open ? childrenHeight : -childrenHeight)
      }
    })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open])

  return (
    <div
      className="overflow-hidden"
      ref={container}
      style={{
        height,
        transition: `height ${TRANSITION_DELAY}ms ease-out`,
      }}
    >
      {children}
    </div>
  )
}

export default Collapsible

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/components/CategoryMenu.tsx from the menu VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { Query } from 'react-apollo'

import categoryWithChildren from '../graphql/categoryWithChildren.graphql'
import StyledLink from './StyledLink'

const CategoryLink: FunctionComponent<CategoryLinkProps> = ({
  href,
  titleTag,
  isTitle,
  name,
}: CategoryLinkProps) => {
  return (
    <StyledLink title={titleTag} to={href} isTitle={isTitle}>
      {name}
    </StyledLink>
  )
}

const CategoryMenu: FunctionComponent<CategoryMenuProps> = ({
  categoryId,
}: CategoryMenuProps) => {
  if (categoryId == null) {
    return null
  }
  return (
    <Query query={categoryWithChildren} variables={{ id: categoryId }}>
      {({ data, loading, error }: any) => {
        if (error || loading) {
          // TODO add loader and error message
          return null
        }

        const {
          category,
          category: { children },
        }: { category: Category } = data
        return (
          <>
            <CategoryLink {...category} isTitle />
            {children?.map((child: Category) => (
              <li key={child.id}>
                <CategoryLink {...child} />
              </li>
            ))}
          </>
        )
      }}
    </Query>
  )
}

interface CategoryMenuProps {
  categoryId: number
  customText?: string
}

interface Category {
  id: number
  titleTag: string
  href: string
  name: string
  children: Category[]
}

interface CategoryLinkProps extends Category {
  isTitle?: boolean
}

export default CategoryMenu

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/__tests__/StyledLink.test.tsx from the menu VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { render } from '@vtex/test-tools/react'
import React from 'react'

import StyledLink from '../components/StyledLink'

describe('Icon should appear at the left', () => {
  function renderComponent(iconPos: 'left' | 'right' | undefined) {
    const props = {
      active: false,
      children: 'Shop',
      highlight: false,
      iconProps: {
        activeClassName: 'rebel-pink',
        id: 'bnd-logo',
        mutedClassName: 'c-action-primary',
        size: 16,
        viewBox: '0 0 16 16',
      },
      iconPosition: iconPos,
      id: 'menu-item-shop',
      params: undefined,
      query: undefined,
      title: 'Shop',
      to: '#',
      treePath:
        'store.home/$before_header.full/header-layout.desktop/header-row#3-desktop/vtex.menu@2.x:menu#websites/menu-item#shop',
    }
    return render(<StyledLink {...props} />)
  }

  it('should be rendered', () => {
    expect(renderComponent('left')).toBeDefined()
  })

  it('should not have icon', () => {
    const props = {
      active: false,
      children: 'Shop',
      highlight: false,
      iconToTheRight: false,
      id: 'menu-item-shop',
      params: undefined,
      query: undefined,
      title: 'Shop',
      to: '#',
      treePath:
        'store.home/$before_header.full/header-layout.desktop/header-row#3-desktop/vtex.menu@2.x:menu#websites/menu-item#shop',
    }

    const { queryByTestId } = render(<StyledLink {...props} />)
    expect(queryByTestId('icon-right')).toBeNull()
    expect(queryByTestId('icon-left')).toBeNull()
  })

  it('should have icon to the left', () => {
    const { getByTestId } = renderComponent('left')
    // eslint-disable-next-line jest/valid-expect
    expect(getByTestId('icon-left'))
  })

  it('should have icon to the right', () => {
    const { getByTestId } = renderComponent('right')
    // eslint-disable-next-line jest/valid-expect
    expect(getByTestId('icon-right'))
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/__tests__/Menu.test.tsx from the menu VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { render } from '@vtex/test-tools/react'
import React from 'react'

import Menu from '../Menu'

describe('Menu Component', () => {
  function renderComponent() {
    return render(<Menu />)
  }

  it('should be rendered', () => {
    expect(renderComponent()).toBeDefined()
  })

  it('should match the snapshot', () => {
    const { asFragment } = renderComponent()
    expect(asFragment()).toMatchSnapshot()
  })

  it('should be editable through storefront', () => {
    expect(Menu.getSchema?.({})).toHaveProperty('title')
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/__tests__/MenuLink.test.tsx from the menu VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { render } from '@vtex/test-tools/react'
import React from 'react'

import Menu from '../index'

describe('MenuLink Component', () => {
  function renderComponent() {
    const props = {
      links: [
        {
          externalPage: 'externalPage',
          internalPage: 'internalPage',
          page: 'page',
          params: 'params',
          position: 'position',
          text: 'text',
          typeOfRoute: 'typeOfRoute',
        },
      ],
    }

    return render(<Menu {...props} />)
  }

  it('should be rendered', () => {
    expect(renderComponent()).toBeDefined()
  })

  it('should match the snapshot', () => {
    const { asFragment } = renderComponent()
    expect(asFragment()).toMatchSnapshot()
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/graphql/categoryWithChildren.graphql from the menu VTEX app.

[Assistant]
Here's the implementation:

```graphql
query categoryWithChildren($id: Int) {
  category(id: $id) {
    cacheId
    id
    href
    name
    titleTag
    children {
      id
      href
      name
      titleTag
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/graphql/category.graphql from the menu VTEX app.

[Assistant]
Here's the implementation:

```graphql
query category($id: Int) {
  category(id: $id) {
    cacheId
    id
    href
    name
    titleTag
  }
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/hooks/useSubmenuImplementation.tsx from the menu VTEX app.

[Assistant]
Here's the implementation:

```tsx
// @ts-expect-error - useTreePath is not a public API
import { useRuntime, useTreePath } from 'vtex.render-runtime'

/** This is a throwaway function, while useChildBlock doesn't return
 * the "implements" block info, or which specialization of the block
 * is being used (i.e. whether its `submenu` or `submenu.accordion`)
 */
const useSubmenuImplementation = () => {
  const runtime = useRuntime()
  const treePathContext = useTreePath()

  const { treePath } = treePathContext
  // @ts-expect-error - extensions is not a public API
  const { extensions } = runtime

  if (!extensions || !treePath) {
    return null
  }

  const submenuTreePath = `${treePath}/submenu`

  const extension = extensions[submenuTreePath]

  if (!extension) {
    return null
  }

  const { component } = extension

  if (
    typeof component === 'string' &&
    component.indexOf('SubmenuAccordion') > -1
  ) {
    return 'submenu.accordion'
  }
  return 'submenu'
}

export default useSubmenuImplementation

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/hooks/useMouseSpeedDebouncer.ts from the menu VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useRef } from 'react'

import { useMouseSpeed } from './useMouseSpeed'

// Max mouse speed in pixels/second to allow the debounced method to be called
const MAX_MOUSE_SPEED = 450
const DEBOUNCE_INTERVAL = 200

export const useMouseSpeedDebouncer = (
  fn: Function,
  {
    delay = DEBOUNCE_INTERVAL,
    maxSpeed = MAX_MOUSE_SPEED,
  }: { delay: number; maxSpeed: number }
) => {
  const timeout = useRef<number | null>(null)
  const { getMouseSpeed } = useMouseSpeed()

  return (...args: any[]) => {
    let lastSpeed: number | null = null

    if (timeout.current) {
      clearTimeout(timeout.current)
      timeout.current = null
    }

    timeout.current = window.setTimeout(function check() {
      const speed = getMouseSpeed()
      if (speed <= maxSpeed) {
        fn(...args)
      } else if (lastSpeed !== null && lastSpeed > maxSpeed) {
        fn(...args)
      } else if (lastSpeed == null || lastSpeed !== speed) {
        timeout.current = window.setTimeout(check, delay)
      }
      lastSpeed = speed
    }, delay)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/hooks/useUrlChange.ts from the menu VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useCallback, useEffect } from 'react'
import { useRuntime } from 'vtex.render-runtime'
import type { Listener } from 'history'

export const useUrlChange = (fn: Listener, deps: unknown[]) => {
  const { history } = useRuntime()

  const memoizedCallback = useCallback(fn, deps)

  useEffect(() => {
    // cancel method is returned to be executed whenever our deps change
    return history?.listen(memoizedCallback)
  }, [memoizedCallback, history])
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of menu/react/hooks/useMouseSpeed.ts from the menu VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useEffect } from 'react'

interface MousePosition {
  x: number | null
  y: number | null
}

const lastPosition: MousePosition = { x: null, y: null }
const currentPosition: MousePosition = { x: null, y: null }

let listenerCount = 0
let lastTimestamp = 0
let mouseSpeed = 0

const handleMouseMove = (e: MouseEvent) => {
  currentPosition.x = e.pageX
  currentPosition.y = e.pageY

  if (lastPosition.x != null && lastPosition.y != null) {
    const now = e.timeStamp
    const distance = Math.sqrt(
      (currentPosition.x - lastPosition.x) ** 2 +
        (currentPosition.y - lastPosition.y) ** 2
    )
    // gives us speed in pixels/second
    const interval = now - lastTimestamp
    mouseSpeed = Math.round((distance / interval) * 1000)
    lastTimestamp = now
  }

  lastPosition.x = currentPosition.x
  lastPosition.y = currentPosition.y
}

export const useMouseSpeed = () => {
  useEffect(() => {
    if (listenerCount === 0) {
      window.addEventListener('mousemove', handleMouseMove)
    }

    listenerCount += 1

    return () => {
      listenerCount -= 1

      if (listenerCount > 0) {
        return
      }

      lastPosition.x = null
      lastPosition.y = null
      currentPosition.x = null
      currentPosition.y = null
      window.removeEventListener('mousemove', handleMouseMove)
    }
  }, [])

  return {
    // Can return NaN for tiny variations
    getMouseSpeed: () => mouseSpeed || 0,
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/docs/README.md from the formula VTEX app.

[Assistant]
Here's the implementation:

```markdown
# VTEX Formula

The VTEX Formula hackathon manager

Sign-up at https://vtex.myvtex.com/formula

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/pages/pages.json from the formula VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "pages": {
    "formula": {
      "path": "/formula"
    },
    "formula/intro": {
      "path": "/formula"
    },
    "formula/projects": {
      "path": "/formula/:edition"
    },
    "formula/projects/list": {
      "path": "/formula/:edition/projects"
    },
    "formula/projects/finalists": {
      "path": "/formula/:edition/finalists"
    },
    "formula/projects/detail": {
      "path": "/formula/:edition/projects/:id"
    }
  },
  "extensions": {
    "formula": {
      "component": "Template"
    },
    "formula/intro": {
      "component": "Intro"
    },
    "formula/projects": {
      "component": "ProjectTemplate"
    },
    "formula/projects/list": {
      "component": "FormulaEdition"
    },
    "formula/projects/finalists": {
      "component": "FormulaEdition"
    },
    "formula/projects/detail": {
      "component": "ProjectDetail"
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/Intro.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { FormattedMessage } from 'react-intl'
import { Link, withRuntimeContext } from 'render'
import { Button, Card } from 'vtex.styleguide'

import Header from './components/Header'
import TeamIcon from './icons/TeamIcon'
import SignupIcon from './icons/SignupIcon'
import DevelopIcon from './icons/DevelopIcon'
import AwardIcon from './icons/AwardIcon'

class IntroPage extends Component<RuntimeProps> {
  componentDidMount() {
    const { runtime: { prefetchPage } } = this.props
    prefetchPage('formula/projects')
    prefetchPage('formula/projects/list')
    prefetchPage('formula/projects/detail')
  }

  render() {
    return (
      <div>
        <Header />
        <div className="tc f2 fw7 mt10">We know you missed Formula</div>
        <div className="flex flex-row-ns flex-column items-center justify-center-ns w-100 pv9 tc f4">
          <div className="ma6 w5">
            <Card>
              <TeamIcon height="68" />
              <div className="pv5">Create a team</div>
              <div className="f6 c-muted-2">Up to five members</div>
            </Card>
          </div>
          <div className="ma6 w5">
            <Card>
              <SignupIcon height="68" />
              <div className="pv5">Sign up</div>
              <div className="f6 c-muted-2">You have until tomorrow!</div>
            </Card>
          </div>
          <div className="ma6 w5">
            <Card>
              <DevelopIcon height="68" />
              <div className="pv5">Develop</div>
              <div className="f6 c-muted-2">Improve VTEX product</div>
            </Card>
          </div>
          <div className="ma6 w5">
            <Card>
              <AwardIcon height="68" />
              <div className="pv5">Win prizes!</div>
              <div className="f6 c-muted-2">Surprise, surprise ;)</div>
            </Card>
          </div>
        </div>
        <div className="pa8 flex center justify-center">
          <Link page="formula/projects/list" params={{edition: "2018.10"}}>
            <Button variation="primary">
              <FormattedMessage id="formula.signup"/>
            </Button>
          </Link>
        </div>
      </div>
    )
  }
}

export default withRuntimeContext(IntroPage)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/global.css from the formula VTEX app.

[Assistant]
Here's the implementation:

```css
@import '//io.vtex.com.br/fonts/fabriga/stylesheet.css';

html,
body,
#render-container,
#render-provider,
.render-container,
.render-provider,

/* Fixes Safari position:fixed + z-index bug https://www.queness.com/code-snippet/16824/fix-mobile-safari-positionfixed-and-z-index-issue */
.safari-positioning {
  transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
}

.font-display,
.font-body {
  font-family: 'Fabriga', 'Helvetica Neue', 'Arial', sans-serif;
}

.c-action-primary {
  color: #f71963;
}

.bg-action-primary {
  background-color: #f71963;
}

.b--action-primary {
  border-color: #f71963;
}

.vtex-pageHeader__container {
  background-color: white;
}

.hover-bg-action-primary:hover {
  background-color: #dd1659;
}

.hover-b--action-primary:hover {
  background-color: #dd1659;
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/ProjectDetail.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component, Fragment } from 'react'
import { Query } from 'react-apollo'
import { FormattedMessage } from 'react-intl'
import { withRuntimeContext } from 'render'
import { PageHeader } from 'vtex.styleguide'

import ProjectDetailQuery from './queries/project.graphql'

import Loading from './components/Loading'
import ProjectForm from './components/ProjectForm'

interface ProjectsData {
  data: any
  params: any
}

interface ProjectState {
  project: Project
}

class ProjectDetail extends Component<ProjectsData & RuntimeProps, ProjectState> {
  constructor(props: any) {
    super(props)

    this.state = {
      project: props.data && props.data.project || {}
    }
  }

  public render() {
    const { params: { edition, id }, runtime } = this.props

    return (
      <Query query={ProjectDetailQuery} skip={id === 'new'} variables={{edition, id}}>
        {({ loading, error, data = {} }) => {
          return (
            <div className="pa7 bg-white mw7 center">
              {loading ? <Loading /> : (
                <Fragment>
                  <PageHeader
                    title={<FormattedMessage id="formula.projectDetails" />}
                    linkLabel={<FormattedMessage id="formula.back" />}
                    onLinkClick={() => {
                      runtime.navigate({page: 'formula/projects/list', params: {edition}})
                    }}
                  />
                  <ProjectForm initialProject={data.project} edition={edition} email={data.profile && data.profile.email}/>
                </Fragment>
              )}
            </div>
          )
        }}
      </Query>
    )
  }
}

export default withRuntimeContext(ProjectDetail)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/typings.d.ts from the formula VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.graphql' {
  import { DocumentNode } from 'graphql'

  const value: DocumentNode
  export default value
}

declare module 'vtex.styleguide' {
  import { ReactElement } from 'react'

  const Badge: ReactElement
  const Button: ReactElement
  const Checkbox: ReactElement
  const Dropdown: ReactElement
  const IconCaretRight: ReactElement
  const Input: ReactElement
  const Tab: ReactElement
  const Tabs: ReactElement
  const Textarea: ReactElement
  const Radio: ReactElement
  const Spinner: ReactElement
  const PageHeader: ReactElement

  export { Badge, Button, Checkbox, Dropdown, IconCaretRight, Input, Tab, Tabs, Textarea, Radio, Spinner, PageHeader }
}

declare module 'render' {
  import { ReactElement } from 'react'
  import { Helmet } from 'react-helmet'

  const NoSSR: ReactElement
  const Link: ReactElement
  const withRuntimeContext: ReactElement

  export { NoSSR, Helmet, Link, withRuntimeContext }
}

interface Project {
  demoURL?: string
  description?: string
  edition?: string
  id?: string
  name?: string
  owner?: string
  team?: ProfileData[]
}

interface ProfileData {
  id: string
  name: string
  email: string
  picture: string
}

interface RuntimeProps {
  runtime: any
}

enum States {
  Registration = 'REGISTRATION',
  Running = 'RUNNING',
  Voting = 'VOTING',
  Results = 'RESULTS'
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/package.json from the formula VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "vtex.formula",
  "version": "0.3.1",
  "scripts": {
    "lint": "tsc --noEmit && tslint -c tslint.json './**/*.ts'"
  },
  "dependencies": {
    "classnames": "^2.2.5",
    "formik": "^1.3.1",
    "prop-types": "^15.5.10",
    "ramda": "^0.25.0",
    "react-countdown-now": "^1.3.0"
  },
  "devDependencies": {
    "@types/graphql": "^0.13.3",
    "@types/node": "^9.4.7",
    "@types/prop-types": "^15.5.2",
    "@types/react": "^16.3.16",
    "@types/react-dom": "^16.0.5",
    "@types/react-helmet": "^5.0.5",
    "@types/react-intl": "^2.3.5",
    "graphql": "^0.13.0",
    "react": "^16.2.0",
    "react-apollo": "^2.0.4",
    "react-dom": "^16.2.0",
    "react-intl": "^2.4.0",
    "tslint": "^5.11.0",
    "tslint-config-vtex": "^2.0.0",
    "typescript": "^3.1.3"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/FormulaEdition.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component, Fragment } from 'react'
import { Query } from 'react-apollo'
import { withRuntimeContext } from 'render'

import FinalistsList from './components/FinalistsList'
import Loading from './components/Loading'
import Navigation from './components/Navigation'
import ProjectsList from './components/ProjectsList'

import InfoQuery from './queries/info.graphql'

interface ProjectsData {
  params: any
}

class FormulaEdition extends Component<RuntimeProps & ProjectsData> {
  constructor(props: any) {
    super(props)
  }

  public render() {
    const { params: { edition }, runtime } = this.props

    return (
      <Query query={InfoQuery} ssr={false} variables={{ edition }}>
        {({ loading, error, data }) => {
          if (loading) {
            return <Loading />
          }

          const state = data.info.status || 'REGISTRATION'

          return (
            <Fragment>
              <Navigation edition={edition} state={state} setPage={(page) => runtime.navigate({page, params: {edition}})} currentPage={runtime.page} />
              {runtime.page === 'formula/projects/list' ? <ProjectsList state={state} edition={edition} /> : <FinalistsList state={state} edition={edition} />}
            </Fragment>
          )
        }}
      </Query>
    )
  }
}

export default withRuntimeContext(FormulaEdition)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/ProjectTemplate.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { Query } from 'react-apollo'

import ProfileQuery from './queries/profile.graphql'

import Header from './components/Header'
import Loading from './components/Loading'
import Timer from './components/Timer'

interface ProjectsData {
  params: {
    edition: string
  }
}

export default class ProjectTemplate extends Component<{} & ProjectsData> {
  constructor(props: any) {
    super(props)
  }

  public render() {
    const { params: { edition } } = this.props
    return (
      <Query query={ProfileQuery} ssr={false}>
        {({ loading, error, data }) => {
          let errorMsg

          if (error) {
            const { graphQLErrors } = error
            const authError = graphQLErrors && graphQLErrors.length > 0 && graphQLErrors.find((e: any) => e.extensions.code === 'UNAUTHENTICATED')
            const forbiddenError = graphQLErrors && graphQLErrors.length > 0 && graphQLErrors.find((e: any) => e.extensions.code === 'FORBIDDEN')
            if (authError) {
              window.location.href = '/_v/auth-server/v1/login?ReturnUrl=' + encodeURIComponent('/formula/2018.10/projects')
              errorMsg = <div>Redirecting to login...</div>
            } else if (forbiddenError) {
              errorMsg = <div>Oops :( Formula is a VTEX-only event. Sorry!</div>
            }
          }

          const firstName = data && data.profile && data.profile.name
            ? data.profile.name.split(' ')[0]
            : ''

          return (
            <div>
              <Header name={firstName} onLogout={this.logout} />
              {!loading && !errorMsg && <Timer edition={edition}/>}
              {loading
                ? <Loading />
                : errorMsg
                  ? <div className="flex center justify-center pa8">{errorMsg}</div>
                  : this.props.children}
            </div>
          )
        }}
      </Query>
    )
  }

  private logout = () => {
    window.location.href = '/admin/logout?redirectUrl=/formula'
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/Template.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { Helmet } from 'render'

import VtexIcon from './icons/VtexIcon'

import './global.css'

export default class FormulaTemplate extends Component {
  render() {
    return (
      <div className="container bg-muted-5">
        <Helmet>
          <title>VTEX Formula</title>
          <link rel="shortcut icon" href="https://io.vtex.com.br/favico/1.3.0/favico.ico"></link>
        </Helmet>
        {this.props.children}
        <footer className="mw7 center gray f8">
          <div className="flex items-center justify-center pa8">
            <VtexIcon />
            <span className="ml3">
              Formula - all rights reserved ©
            </span>
          </div>
        </footer>
      </div>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/locales/en.json from the formula VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "formula.title": "Formula",
  "formula.hello": "Hello,",
  "formula.signup": "Let's do this!",
  "formula.logout": "Logout",
  "formula.seeDetails": "Edit",
  "formula.team": "Team",
  "formula.back": "Back",
  "formula.save": "Save",
  "formula.join": "Join Team",
  "formula.leave": "Leave Team",
  "formula.delete": "Delete",
  "formula.newProject": "Create a project",
  "formula.status.registration": "It's almost time!",
  "formula.status.running": "Run, Forrest, run!",
  "formula.status.voting": "And it's a wrap!",
  "formula.status.voting.details": "Time to vote.",
  "formula.status.results": "That was great.",
  "formula.status.results.details": "Thanks!",
  "formula.projectDetails": "Project",
  "formula.viewDemo": "View Demo"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/joinProject.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation JoinProject(
  $edition: String!
  $id: String!
) {
  joinProject(edition: $edition, id: $id) {
    team {
      name
      email
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/finalists.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Finalists ($edition: String!) {
  finalists (edition: $edition) {
    id
    name
    description
    demoURL
    owner
    team {
      id
      email
      name
      picture
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/info.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Info ($edition: String!) {
  info (edition: $edition) {
    status
    timeRemainingSeconds
    timeTotalSeconds
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/leaveProject.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation LeaveProject(
  $edition: String!
  $id: String!
) {
  leaveProject(edition: $edition, id: $id) {
    team {
      name
      email
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/profile.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Profile {
  profile {
    id
    name
    email
    picture
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/projects.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Projects ($edition: String!) {
  profile {
    email
  }
  projects (edition: $edition) {
    id
    name
    description
    demoURL
    owner
    team {
      id
      email
      name
      picture
    }
  }
  votes (edition: $edition) {
    projectID
    execution
    relevance
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/deleteProject.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation DeleteProject(
  $edition: String!
  $id: String!
) {
  deleteProject(edition: $edition, id: $id)
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/updateProject.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation UpdateProject(
  $edition: String!
  $id: String
  $demoURL: String
  $description: String
  $name: String!
) {
  updateProject(edition: $edition, id: $id, demoURL: $demoURL, description: $description, name: $name) {
    id
    name
    description
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/project.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
query Project ($edition: String!, $id: String!) {
  profile {
    email
  }
  project (edition: $edition, id: $id) {
    id
    name
    description
    demoURL
    owner
    team {
      id
      email
      name
      picture
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/queries/vote.graphql from the formula VTEX app.

[Assistant]
Here's the implementation:

```graphql
mutation Vote(
  $edition: String!
  $id: String!
  $execution: Int!
  $relevance: Int!
) {
  updateVote(edition: $edition, projectID: $id, execution: $execution, relevance: $relevance) {
    projectID
    userID
    relevance
    execution
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/components/ProjectCard.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component, Fragment } from 'react'
import { Mutation } from 'react-apollo'
import { FormattedMessage } from 'react-intl'
import { Link } from 'render'
import { Button, Spinner } from 'vtex.styleguide'

import JoinProjectMutation from '../queries/joinProject.graphql'
import LeaveProjectMutation from '../queries/leaveProject.graphql'
import ProjectsQuery from '../queries/projects.graphql'
import voteMutation from '../queries/vote.graphql'

interface ProjectCardProps {
  email: string
  hasTeam: boolean
}

function getVoteClass(value, current, state, voting) {
  const activeClasses = 'br-pill bg-emphasis c-on-base--inverted flex items-center justify-center fw3 f4 mr4-ns' + (state === 'RESULTS' ? ' bg-muted-2' : '')
  const inactiveClasses = 'br-pill bg-base ba b--muted-3 c-muted-3 flex items-center justify-center fw3 f4 mr4-ns'
  let classes = value >= current ? activeClasses : inactiveClasses
  if (state === 'VOTING' && !voting) {
    classes += ' pointer'
  }
  return classes
}

export default class ProjectCard extends Component<ProjectCardProps & Project> {
  constructor(props: any) {
    super(props)

    this.state = {
      votingCriteria: null,
      votingScore: null
    }
  }

  public render() {
    const { id, edition, name, description, owner, demoURL, team, email, hasTeam, vote, state} = this.props

    const refetchProjectsQuery = {
      query: ProjectsQuery,
      variables: {
        edition,
      }
    }

    const isOwner = owner === email

    const isInTeam = team && team.find((t) => t.email === email)

    const joinOrLeave = isInTeam ? (
      <Mutation mutation={LeaveProjectMutation} refetchQueries={[refetchProjectsQuery]}>
        {(leaveProject) => {
          return (
            <Button onClick={() => leaveProject({variables: {edition, id}})}>
              <FormattedMessage id="formula.leave" />
            </Button>
          )
        }}
      </Mutation>
    ) : !hasTeam ? (
      <Mutation mutation={JoinProjectMutation} refetchQueries={[refetchProjectsQuery]}>
        {(joinProject) => {
          return (
            <Button onClick={() => joinProject({variables: {edition, id}})}>
              <FormattedMessage id="formula.join" />
            </Button>
          )
        }}
      </Mutation>
    ) : null

    return (
      <div className="bg-base ma5 ba1 b-dark-silver center mw7 pa7 mt7 br2">
        <div className="inline-flex w-100">
          <div className="w-100">
            <div className="flex justify-between items-center pb6 w-100">
              <div className="f4 fw5 pb3">{name}</div>
              {state === 'REGISTRATION' || state === 'RUNNING' || state === 'VOTING' ?
              <div className="h1">
                <Link page="formula/projects/detail" params={{edition, id}}>
                  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                  <rect width="16" height="16" fill="white"/>
                  <path d="M2 14.5H14" stroke="#f71963" strokeWidth="1.4" strokeMiterlimit="10" strokeLinecap="round" strokeLinejoin="round"/>
                  <path d="M10.1429 1.5L12.7143 4.1L5.42857 11.4667L2 12.3333L2.85714 8.86667L10.1429 1.5Z" stroke="#f71963" strokeWidth="1.4" strokeMiterlimit="10" strokeLinecap="round" strokeLinejoin="round"/>
                  <path d="M8.42859 3.2334L11 5.8334" stroke="#f71963" strokeWidth="1.4" strokeMiterlimit="10" strokeLinecap="round" strokeLinejoin="round"/>
                  </svg>
                </Link>
              </div>
              : null}
            </div>
            <div className="f5 bb b--muted-5 mb7 pb7 fw3 lh-copy">{description}</div>
            {demoURL && <div className="f5 bb b--muted-5 mb7 pb7 fw3 lh-copy">
              <a className="link c-emphasis" href={demoURL} target="__blank">
                <FormattedMessage id="formula.viewDemo"/>
              </a>
            </div>}
          </div>
        </div>
        {state !== 'VOTING' ? <section>
          <div className="f4 fw5"><FormattedMessage id="formula.team" /></div>
          <ul className="list pl0 mb7 lh-copy">
            {team && team.map((u) => <li key={u.id}>{u.name} - {u.email}</li>)}
          </ul>
        </section> : null}
        {state === 'REGISTRATION' || state === 'RUNNING' ? !isOwner && joinOrLeave : null}

        {state === 'VOTING' || state === 'RESULTS' ?
        <div>
          <div className="flex justify-between fw7">
            <div>Evaluation</div>
            <div>Total Score: {vote.relevance + vote.execution}</div>
          </div>
          <div className="pt6">
            <div className="c-muted-2 f5">
              Criteria #1
            </div>
            <div className="f6 pt3">
              Project impact on VTEX
            </div>
          </div>
          <div className="flex mt7 w-100 bb b--muted-5 pb7 justify-start-ns justify-between">
            <Mutation mutation={voteMutation} refetchQueries={[refetchProjectsQuery]} awaitRefetchQueries>
              {(updateVote) => (
                <Fragment>
                  {[1,2,3,4,5].map(this.renderVotingCriteria('relevance', updateVote))}
                </Fragment>
              )}
            </Mutation>
          </div>
          <div className="pt6">
            <div className="c-muted-2 f5">
              Criteria #2
            </div>
            <div className="f6 pt3">
              Project quality level
            </div>
          </div>
          <div className="flex mt7 w-100 justify-start-ns justify-between">
            <Mutation mutation={voteMutation} refetchQueries={[refetchProjectsQuery]} awaitRefetchQueries>
              {(updateVote) => (
              <Fragment>
                {[1,2,3,4,5].map(this.renderVotingCriteria('execution', updateVote))}
              </Fragment>
              )}
            </Mutation>
          </div>
        </div> : null}
      </div>
    )
  }

  private renderVotingCriteria = (criteria: string, updateVote: any) => (idx: number) => {
    const {state, vote, edition, id} = this.props
    const votingCriteria = this.state.votingCriteria === criteria
    const votingScore = this.state.votingScore

    const handleVoteClick = () => {
      if (this.state.votingCriteria || state !== 'VOTING') {
        return null
      }
      this.setState({
        votingCriteria: criteria,
        votingScore: idx,
      })
      return updateVote({variables: {
        edition,
        id,
        ...vote,
        [criteria]: idx,
      }}).then(() => {
        this.setState({
          votingCriteria: null,
          votingScore: null,
        })
      })
    }

    return (
      <div
        key={`relevance-${idx}`}
        className={getVoteClass(votingCriteria ? votingScore - 1 : vote[criteria], idx, state, votingCriteria)}
        style={{ width: '48px', height: '48px' }}
        onClick={handleVoteClick}>
        {votingCriteria && votingScore === idx ? <Spinner /> : idx}
      </div>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/components/BlockedFinalists.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import OwlIcon from '../icons/OwlIcon'

export default class FinalistsList extends Component<{}> {
  public render () {
    return (
      <div className="flex justify-center w-100">
        <div className="bg-base ma5 ba1 b-dark-silver center mw7 pa7 mt7 br2 w-100">
          <div className="flex items-center justify-center pt9">
            <OwlIcon height="100" />
          </div>
          <div className="f3 fw7 tc pt9">Nothing to see here, mate</div>
          <div className="f5 tc pb9 pt3">Go get some pizza and come back after Formula is done.</div>
        </div>
      </div>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/components/ProjectsList.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { Query } from 'react-apollo'

import ProjectsQuery from '../queries/projects.graphql'

import Loading from './Loading'
import ProjectCard from './ProjectCard'

interface ProjectsListData {
  edition: string
  state: States
}

export default class ProjectsList extends Component<ProjectsListData> {
  public render () {
    const { edition, state } = this.props
    return (
      <Query query={ProjectsQuery} variables={{ edition }}>
        {({ loading, error, data }) => {
          if (loading) {
            return <Loading />
          }

          const hasTeam = data.projects && !!data.projects.find((p: Project) => p.team && p.team.find(({ email }) => email === data.profile.email))
          return data.projects.map((p: Project) => {
            const vote = data.votes.find(current => current.projectID === p.id) || {execution: 0, relevance: 0}

            return <ProjectCard vote={vote} state={state} key={p.id} {...p} email={data.profile.email} edition={edition} hasTeam={hasTeam} />
          })
        }}
      </Query>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/components/Timer.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { Query } from 'react-apollo'
import Countdown from 'react-countdown-now'
import { FormattedMessage } from 'react-intl'

import InfoQuery from '../queries/info.graphql'
import Loading from './Loading'

interface TimerProps {
  edition: string
}

const nowMillis = new Date().getTime()

let refreshTimeout: any

export default class Timer extends Component<TimerProps> {
  public render() {
    const { edition } = this.props
    return (
      <Query query={InfoQuery} ssr={false} variables={{ edition }}>
        {({ loading, error, data = {} }) => {
          if (loading || !data.info) {
            return <Loading />
          }

          const remaining = data && data.info && data.info.timeRemainingSeconds
          const status = data && data.info && data.info.status
          const total = data && data.info && data.info.timeTotalSeconds
          const countdownRunning = status === 'REGISTRATION' || status === 'RUNNING'

          if (countdownRunning && !refreshTimeout) {
            refreshTimeout = setTimeout(() => {
              console.log('Time\'s up!')
              window.location.reload()
            }, remaining * 1000)
          }

          const barWidth = status === 'REGISTRATION'
            ? 0
            : status !== 'RUNNING'
              ? '100%'
              : `${Math.round(((total - remaining) / total) * 100)}%`

          const afterContent = status === 'VOTING'
            ? <FormattedMessage id="formula.status.voting.details"/>
            : status === 'RESULTS'
              ? <FormattedMessage id="formula.status.results.details"/>
              : null

          const countdown = countdownRunning &&
            <Countdown
              date={nowMillis + remaining * 1000}
              daysInHours={true} />

          return (
            <div className="bg-serious-black white">
              <div className="center mw7 pv7 ph5">
                <div className="f5 fw3">
                  <FormattedMessage id={`formula.status.${status.toLowerCase()}`} />
                </div>
                <div className="fw3 pb5 dn-ns db" style={{fontSize: '5em'}}>
                  { countdown || afterContent }
                </div>
                <div className="fw3 pb5 dn db-ns" style={{fontSize: countdownRunning ? '10em' : '7em'}}>
                  { countdown || afterContent }
                </div>
                <div className="w-100 bg-marine h2 relative mb7 br2" style={{height: '0.25rem'}}>
                  <div className="bg-rebel-pink h2 br2" style={{width: barWidth, height: '0.25rem'}}></div>
                </div>
              </div>
            </div>
          )
        }}
      </Query>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/components/ProjectForm.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { Formik } from 'formik'
import React, { Component } from 'react'
import { Mutation } from 'react-apollo'
import { FormattedMessage } from 'react-intl'
import { withRuntimeContext } from 'render'
import { Button, Input, Textarea } from 'vtex.styleguide'

import DeleteProjectMutation from '../queries/deleteProject.graphql'
import ProjectDetailQuery from '../queries/project.graphql'
import ProjectsQuery from '../queries/projects.graphql'
import UpdateProjectMutation from '../queries/updateProject.graphql'

interface ProjectFormProps {
  initialProject: Project
  edition: string
  email: string
}

interface ProjectFormState {
  project: Project
}

class ProjectForm extends Component<ProjectFormProps & RuntimeProps, ProjectFormState> {
  constructor(props: any) {
    super(props)

    this.state = {
      project: props.initialProject || {},
    }
  }

  public render() {
    const { edition, email } = this.props
    const { project } = this.state

    const team = project && project.id && project.team && (
      <ul>
        {project.team.map((u) => <li key={u.id}>{u.name} - {u.email}</li>)}
      </ul>
    )

    const isOwner = project.owner === email

    const refetchProjectsQuery = {
      query: ProjectsQuery,
      variables: {
        edition,
      }
    }

    const refetchProjectDetailQuery = {
      query: ProjectDetailQuery,
      variables: {
        edition,
        id: project.id,
      }
    }

    const handleDeleteSuccess = () => this.props.runtime.navigate({page: 'formula/projects/list', params: {edition}})

    const deleteButton = isOwner && project.id && (
      <Mutation mutation={DeleteProjectMutation} refetchQueries={[refetchProjectsQuery, refetchProjectDetailQuery]}>
        {(deleteProject) => {
          return (
            <Button variation="tertiary" onClick={() => deleteProject({variables: {edition, id: project.id}}).then(handleDeleteSuccess)} >
              <FormattedMessage id="formula.delete" />
            </Button>
          )
        }}
      </Mutation>
    )

    return (
      <div className="bg-white ma5 ba1 b-dark-silver">
        <Mutation mutation={UpdateProjectMutation} refetchQueries={[refetchProjectsQuery]}>
          {(updateProject, { data }) => {
            console.log('data on mutation', data)
            return (
              <Formik
                initialValues={project}
                validate={values => {
                  const errors: any = {}
                  if (!values.name) {
                    errors.name = 'Required'
                  }
                  return errors
                }}
                onSubmit={(values, { setSubmitting }) => {
                  updateProject({
                    variables: {
                      edition,
                      ...project,
                      ...values,
                    }
                  }).then((d: any) => {
                    console.log('updateProject.then', d.data.updateProject.id)
                    this.setState({
                      project: {
                        ...project,
                        id: d.data.updateProject.id,
                      }
                    })
                    setSubmitting(false)
                  })
                }}
              >
                {({
                  values,
                  errors,
                  touched,
                  handleChange,
                  handleBlur,
                  handleSubmit,
                  isSubmitting,
                }) => (
                  <form onSubmit={handleSubmit}>
                    <div className="mb5 gray f8">
                      {project.id}
                    </div>
                    <div className="mb5">
                      <Input
                        label="Name"
                        name="name"
                        error={errors.name && touched.name}
                        errorMessage={touched.name && errors.name}
                        onChange={handleChange}
                        onBlur={handleBlur}
                        value={values.name} />
                    </div>
                    <div className="mb5">
                      <Textarea
                        label="Description"
                        name="description"
                        type="textarea"
                        error={errors.description && touched.description}
                        errorMessage={touched.description && errors.description}
                        onChange={handleChange}
                        onBlur={handleBlur}
                        value={values.description} />
                    </div>
                    <div className="mb5">
                      <Input
                        label="Demo URL"
                        name="demoURL"
                        error={errors.demoURL && touched.demoURL}
                        errorMessage={touched.demoURL && errors.demoURL}
                        onChange={handleChange}
                        onBlur={handleBlur}
                        value={values.demoURL} />
                    </div>
                    <div className="mb5">
                      <p>
                        <FormattedMessage id="formula.team" />
                      </p>
                      {team}
                    </div>
                    {deleteButton}
                    <Button type="submit" disabled={isSubmitting}>
                      <FormattedMessage id="formula.save" />
                    </Button>
                  </form>
                )}
              </Formik>
            )
          }}
        </Mutation>
      </div>
    )
  }
}

export default withRuntimeContext(ProjectForm)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/components/Header.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { FormattedMessage } from 'react-intl'
import { Button } from 'vtex.styleguide'

import VtexIcon from '../icons/VtexIcon'

interface HeaderProps {
  name?: string
  onLogout?: () => void
}

export default class Header extends Component<HeaderProps> {
  public render() {
    const { name, onLogout } = this.props

    const title = (
      <h3><FormattedMessage id="formula.title"/></h3>
    )

    const hello = name && (
      <div className="dn db-ns">
        <FormattedMessage id="formula.hello"/> {name}
      </div>
    )

    const logout = onLogout && (
      <Button variation="tertiary" onClick={onLogout}>
        <span className="white">
         <FormattedMessage id="formula.logout"/>
        </span>
      </Button>
    )

    return (
      <header className="bg-serious-black pa7 white">
        <div className="flex items-center justify-between">
          <div className="flex items-center">
            <VtexIcon fill="white" logo/>
            <div className="pr3">
              {title}
            </div>
            {hello}
          </div>
          <div>
            {logout}
          </div>
        </div>
      </header>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/components/Loading.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { Spinner } from 'vtex.styleguide'

export default class Timer extends Component {
  public render() {
    return (
      <div className="flex justify-center pa8 w-100">
        <Spinner />
      </div>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/components/FinalistsList.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { Query } from 'react-apollo'

import FinalistsQuery from '../queries/finalists.graphql'

import BlockedFinalists from './BlockedFinalists'
import Loading from './Loading'
import ProjectCard from './ProjectCard'

interface ProjectsListData {
  edition: string
  state: States
}

export default class FinalistsList extends Component<ProjectsListData> {
  public count: number = 0

  public getWinnerIcon() {
    this.count++
    if (this.count === 3) { return '🥉 ' }
    if (this.count === 2) { return '🥈 ' }
    if (this.count === 1) { return '🥇 ' }

    return ''
  }

  public render () {
    const { edition, state } = this.props

    if (state !== 'RESULTS') {
      return <BlockedFinalists />
    }

    return (
      <Query query={FinalistsQuery} variables={{ edition }}>
        {({ loading, error, data }) => {
          if (loading) {
            return <Loading />
          }

          return data.finalists.map((p: Project) =>
            <ProjectCard key={p.id} {...p} email={''} edition={edition} hasTeam={true} />
          )
        }}
      </Query>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/components/Navigation.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'
import { FormattedMessage } from 'react-intl'
import { Link, withRuntimeContext } from 'render'
import { Button, Tab, Tabs } from 'vtex.styleguide'

interface NavigationProps {
  edition: string
  currentPage: string
  setPage: (url: string) => void
}

export default class Navigation extends Component<NavigationProps> {
  public render() {
    const { edition, currentPage, setPage, state } = this.props

    return (
      <div className="relative mw7 center mt7">
        <Tabs>
          <Tab label="Projects" active={currentPage === 'formula/projects/list'} onClick={() => setPage('formula/projects/list')} />
          <Tab label="Finalists" active={currentPage === 'formula/projects/finalists'} onClick={() => setPage('formula/projects/finalists')} />
        </Tabs>

        {state === 'REGISTRATION' || state === 'RUNNING' ?
        <Link page="formula/projects/detail" params={{edition, id: 'new'}} className="absolute" style={{right: '0em', bottom: '1em'}}>
          <Button size="small" className="pb4">
            <FormattedMessage id="formula.newProject" />
          </Button>
        </Link>
        :null}
      </div>
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/RefreshIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'

class RefreshIcon extends Component {
  public render() {
    return (
      <svg width="16" height="16" viewBox="0 0 1792 1792">
        <path d="M1639 1056q0 5-1 7-64 268-268 434.5t-478 166.5q-146 0-282.5-55t-243.5-157l-129 129q-19 19-45 19t-45-19-19-45v-448q0-26 19-45t45-19h448q26 0 45 19t19 45-19 45l-137 137q71 66 161 102t187 36q134 0 250-65t186-179q11-17 53-117 8-23 30-23h192q13 0 22.5 9.5t9.5 22.5zm25-800v448q0 26-19 45t-45 19h-448q-26 0-45-19t-19-45 19-45l138-138q-148-137-349-137-134 0-250 65t-186 179q-11 17-53 117-8 23-30 23h-199q-13 0-22.5-9.5t-9.5-22.5v-7q65-268 270-434.5t480-166.5q146 0 284 55.5t245 156.5l130-129q19-19 45-19t45 19 19 45z"/>
      </svg>
    )
  }
}

export default RefreshIcon

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/SignupIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'

class SignupIcon extends Component {
  public render() {
    return (
      <svg height={this.props.height} width={this.props.width} version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" xmlSpace="preserve">
        <title>sign</title>
        <g fill="#f71963" stroke="#f71963" strokeLinecap="round" strokeWidth="4">
          <line fill="none" x1="2" x2="62" y1="62" y2="62"/>
          <path d="M5,55 c0,0,3.239-13.239,6-16L45.929,4.071c2.761-2.761,7.239-2.761,10,0l0,0c2.761,2.761,2.761,7.239,0,10L21,49C18.239,51.761,5,55,5,55 z" fill="none" stroke="#162031"/>
          <polyline fill="none" points=" 49,38 61,26 57,22 "/>
          <path d="M10.792,39.227 C13.208,38.963,15.92,39.92,18,42l0,0c2.081,2.081,3.028,4.8,2.764,7.216" fill="none" stroke="#162031"/>
        </g>
      </svg>
    )
  }
}

export default SignupIcon

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/AwardIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'

class AwardIcon extends Component {
  public render() {
    return (
      <svg height={this.props.height} width={this.props.width} version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" xmlSpace="preserve">
        <title>award</title>
        <g fill="#f71963" stroke="#f71963" strokeLinecap="round" strokeWidth="4">
          <polyline fill="none" points="43,40.892 43,61 32,56 21,61 21,40.891 "/>
          <circle cx="32" cy="23" fill="none" r="8"/>
          <circle cx="32" cy="23" fill="none" r="21" stroke="#162031"/>
        </g>
      </svg>
    )
  }
}

export default AwardIcon

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/DevelopIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'

class DevelopIcon extends Component {
  public render() {
    return (
      <svg height={this.props.height} width={this.props.width} version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" xmlSpace="preserve">
        <title>window dev</title>
        <g fill="#f71963" stroke="#f71963" strokeLinecap="round" strokeWidth="4">
          <polyline fill="none" points=" 22,34 18,38 22,42 "/>
          <polyline fill="none" points=" 42,34 46,38 42,42 "/>
          <line fill="none" x1="28" x2="36" y1="46" y2="30"/>
          <line fill="none" x1="10" x2="14" y1="13" y2="13"/>
          <line fill="none" x1="20" x2="24" y1="13" y2="13"/>
          <line fill="none" x1="43" x2="54" y1="13" y2="13"/>
          <line fill="none" stroke="#162031" x1="2" x2="62" y1="20" y2="20"/>
          <rect height="52" width="60" fill="none" stroke="#162031" x="2" y="6"/>
        </g>
      </svg>
    )
  }
}

export default DevelopIcon

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/OwlIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'

class OwlIcon extends Component {
  public render() {
    return (
      <svg height={this.props.height} width={this.props.width} version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" xmlSpace="preserve">
        <title>owl</title>
        <g fill="#f71963" stroke="#f71963" strokeLinecap="round" strokeWidth="3" transform="translate(0.5 0.5)">
          <path d="M51.5970459,14 c-1.0246582-2.0047607-2.3737793-3.8895264-4.0406494-5.5563965C43.2606201,4.1478271,37.630249,1.9998779,32,1.9998779 S20.7393799,4.1478271,16.4436035,8.4436035C14.7767334,10.1104736,13.4276123,11.9952393,12.4029541,14" fill="none"/>
          <path d="M13.6785889,36.2019043 l13.0579834,22.6760254h0.0294189C27.7873535,60.7302246,29.7352295,62,32,62s4.2126465-1.2697754,5.2340088-3.1220703h0.0294189 l13.0579834-22.6760254" fill="none"/>
          <path d="M14.8954649,38.3150864 C11.950819,40.5018234,10,44.050396,10,48c0,2.7181396,0.9143066,5.2167969,2.4377441,7.2287598 c1.0566854-3.6444054,4.2928905-6.4931564,8.0878925-7.1365166" fill="none"/>
          <path d="M49.1045341,38.3150864 C52.0491829,40.5018234,54,44.050396,54,48c0,2.7181396-0.9143066,5.2167969-2.4377441,7.2287598 c-1.0566864-3.6444054-4.2928886-6.4931564-8.0878944-7.1365166" fill="none"/>
          <path d="M28.0673122,34.8776932 C25.9344444,36.8232307,23.1143875,38,20,38c-6.6274166,0-12-5.3725815-12-12c0-0.5396099,0.0300512-1.0280037,0.099062-1.5487537" fill="none" stroke="#162031"/>
          <path d="M35.9304466,34.8942566 C38.0625038,36.8359375,40.88908,38,44,38c6.6274185,0,12-5.3725815,12-12c0-0.5396099-0.0300522-1.0280037-0.0990601-1.5487537" fill="none" stroke="#162031"/>
          <path d="M32,26H13.9999876 C7.3725777,26,2,20.6274223,2,14.0000124V14h18.0000114C26.6274223,14,32,19.3725777,32,25.9999886V26z" fill="none" stroke="#162031"/>
          <path d="M32,26h18.0000114 C56.6274223,26,62,20.6274223,62,14.0000124V14H43.9999886C37.3725777,14,32,19.3725777,32,25.9999886V26" fill="none" stroke="#162031"/>
          <path d="M24,26 c0,2.2091389-1.7908611,4-4,4s-4-1.7908611-4-4" fill="none" stroke="#162031"/>
          <path d="M48,26 c0,2.2091389-1.7908592,4-4,4s-4-1.7908611-4-4" fill="none" stroke="#162031"/>
          <path d="M28,34 c0-2.2091389,1.7908611-8,4-8s4,5.7908611,4,8s-1.7908592,8-4,8S28,36.2091408,28,34z" fill="none" stroke="#162031"/>
        </g>
      </svg>
    )
  }
}

export default OwlIcon

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/TeamIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'

class TeamIcon extends Component {
  public render() {
    return (
      <svg height={this.props.height} width={this.props.width} version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" xmlSpace="preserve">
        <title>multiple 11</title>
        <g fill="#f71963" stroke="#f71963" strokeLinecap="round" strokeWidth="4">
          <path d="M21.427,27.439 C20.464,25.41,18.395,24,16,24H8c-3.314,0-6,2.686-6,6v8l4,2l1,14h11" fill="none"/>
          <circle cx="12" cy="12" fill="none" r="6"/>
          <path d="M42.573,27.439 C43.536,25.41,45.605,24,48,24h8c3.314,0,6,2.686,6,6v8l-4,2l-1,14H46" fill="none"/>
          <circle cx="52" cy="12" fill="none" r="6"/>
          <path d="M38,62H26l-1-16l-5-1V32 c0-4.418,3.582-8,8-8h8c4.418,0,8,3.582,8,8v13l-5,1L38,62z" fill="none" stroke="#162031"/>
          <circle cx="32" cy="10" fill="none" r="8" stroke="#162031"/>
        </g>
      </svg>
    )
  }
}

export default TeamIcon

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/VtexIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component, Fragment } from 'react'

class VtexIcon extends Component<{fill?: string, logo?: boolean}> {
  public render() {
    const {fill = '#F71963', logo = null} = this.props
    const vtex = !logo && (
      <Fragment>
        <path d="M39.3559 0H7.58867C5.12544 0 3.54811 2.59188 4.70074 4.7466L7.87832 10.7021H2.11774C1.75293 10.7022 1.39433 10.7956 1.07667 10.9732C0.759019 11.1507 0.493077 11.4065 0.304605 11.7156C0.116133 12.0248 0.0115195 12.3769 0.000898204 12.7378C-0.00972314 13.0987 0.0740067 13.4562 0.243979 13.7757L10.4647 32.9227C10.6449 33.2595 10.9144 33.5412 11.2442 33.7378C11.5741 33.9343 11.9518 34.0381 12.3368 34.0381C12.7218 34.0381 13.0995 33.9343 13.4293 33.7378C13.7592 33.5412 14.0287 33.2595 14.2088 32.9227L16.9846 27.7507L20.4672 34.2762C21.6928 36.5714 25.0131 36.5756 26.243 34.283L42.1657 4.62638C43.2912 2.52883 41.7555 0 39.3559 0ZM25.0862 12.6711L18.2205 25.4615C18.1005 25.6854 17.9212 25.8728 17.7017 26.0034C17.4823 26.1341 17.231 26.2032 16.9749 26.2032C16.7188 26.2032 16.4675 26.1341 16.2481 26.0034C16.0286 25.8728 15.8492 25.6854 15.7292 25.4615L8.92986 12.7249C8.81622 12.5125 8.7599 12.2747 8.76636 12.0345C8.77283 11.7943 8.84185 11.5598 8.96675 11.3537C9.09166 11.1476 9.2682 10.977 9.4793 10.8582C9.69039 10.7395 9.92888 10.6768 10.1717 10.6761H23.8749C24.1116 10.6761 24.3443 10.7367 24.5503 10.8521C24.7564 10.9675 24.9287 11.1336 25.0507 11.3345C25.1726 11.5353 25.2399 11.7639 25.2462 11.9981C25.2524 12.2323 25.1973 12.4642 25.0862 12.6711Z" fill={fill}/>
        <path d="M73.1448 13.7581H69.6699V25.5456C69.6697 25.653 69.6265 25.7559 69.5497 25.8319C69.473 25.9078 69.369 25.9506 69.2605 25.9508H66.5807C66.4722 25.9506 66.3681 25.9078 66.2914 25.8319C66.2147 25.7559 66.1715 25.653 66.1713 25.5456V13.7581H62.676C62.6234 13.7602 62.5708 13.7519 62.5215 13.7335C62.4722 13.7152 62.4271 13.6873 62.389 13.6513C62.3508 13.6154 62.3203 13.5723 62.2992 13.5245C62.2782 13.4767 62.2671 13.4252 62.2666 13.373V11.2881C62.2671 11.236 62.2782 11.1845 62.2992 11.1367C62.3203 11.0889 62.3508 11.0457 62.389 11.0098C62.4271 10.9739 62.4722 10.9459 62.5215 10.9276C62.5708 10.9093 62.6234 10.9009 62.676 10.9031H73.1439C73.2524 10.898 73.3585 10.9357 73.439 11.0078C73.5196 11.08 73.568 11.1807 73.5737 11.2881V13.3739C73.5678 13.4809 73.5194 13.5814 73.4391 13.6533C73.3587 13.7252 73.253 13.7629 73.1448 13.7581Z" fill={fill}/>
        <path d="M84.2999 25.8659C83.5838 25.9668 82.3794 26.129 80.1701 26.129C77.531 26.129 75.1995 25.4607 75.1995 21.7759V15.0503C75.1995 11.3655 77.5523 10.7173 80.1905 10.7173C82.3989 10.7173 83.5838 10.8795 84.2999 10.9804C84.5861 11.0208 84.7093 11.1225 84.7093 11.3856V13.2713C84.709 13.3787 84.6658 13.4817 84.5891 13.5576C84.5124 13.6336 84.4084 13.6763 84.2999 13.6766H79.9866C79.0251 13.6766 78.6777 14.0002 78.6777 15.0536V16.8964H84.1368C84.2453 16.8967 84.3493 16.9394 84.426 17.0154C84.5027 17.0913 84.546 17.1943 84.5462 17.3017V19.2252C84.546 19.3326 84.5027 19.4355 84.426 19.5115C84.3493 19.5874 84.2453 19.6302 84.1368 19.6304H78.6777V21.7767C78.6777 22.8293 79.0251 23.1538 79.9866 23.1538H84.2999C84.4084 23.154 84.5124 23.1968 84.5891 23.2727C84.6658 23.3487 84.709 23.4516 84.7093 23.559V25.4422C84.7093 25.7036 84.5861 25.8255 84.2999 25.8659Z" fill={fill}/>
        <path d="M99.7342 25.9466H96.4818C96.216 25.9466 96.0928 25.8625 95.9501 25.6431L93.1301 21.2117L90.5752 25.5455C90.4316 25.7885 90.2889 25.9508 90.0655 25.9508H87.0383C86.8336 25.9508 86.7317 25.8289 86.7317 25.6876C86.7356 25.6381 86.7495 25.5898 86.7724 25.5455L91.2037 18.2314L86.7266 11.2864C86.7039 11.2493 86.6899 11.2077 86.6858 11.1645C86.6931 11.0901 86.729 11.0213 86.7861 10.9724C86.8431 10.9234 86.917 10.898 86.9924 10.9014H90.2855C90.5106 10.9014 90.6745 11.104 90.7951 11.2864L93.4121 15.3764L95.945 11.2864C96.0469 11.104 96.2312 10.9014 96.4546 10.9014H99.4819C99.5573 10.898 99.6312 10.9234 99.6882 10.9724C99.7453 11.0213 99.7812 11.0901 99.7885 11.1645C99.7844 11.2077 99.7704 11.2493 99.7477 11.2864L95.2927 18.2743L99.9388 25.5455C99.9751 25.6073 99.9961 25.6768 100 25.7481C100.001 25.8658 99.8981 25.9466 99.7342 25.9466Z" fill={fill}/>
        <path d="M57.3639 10.9434C57.2909 10.9436 57.2201 10.9688 57.1638 11.0148C57.1074 11.0608 57.0689 11.1247 57.0547 11.1956L54.0852 22.0735C54.0445 22.2962 53.9833 22.377 53.799 22.377C53.6147 22.377 53.5535 22.2929 53.5128 22.0735L50.5399 11.1931C50.5257 11.1222 50.4872 11.0583 50.4308 11.0123C50.3745 10.9663 50.3038 10.9411 50.2307 10.9409H47.308C47.2604 10.9409 47.2135 10.9516 47.1707 10.9721C47.1279 10.9926 47.0904 11.0223 47.0608 11.0592C47.0313 11.096 47.0105 11.139 47 11.1849C46.9896 11.2308 46.9897 11.2784 47.0005 11.3242C47.0005 11.3242 50.6274 23.7994 50.6673 23.9222C51.1514 25.4085 52.3262 26.1189 53.8211 26.1189C55.2447 26.1189 56.4873 25.3749 56.9732 23.9264C57.0309 23.7582 60.5772 11.3234 60.5772 11.3234C60.5877 11.2776 60.5878 11.2301 60.5773 11.1843C60.5667 11.1385 60.5459 11.0957 60.5164 11.0589C60.4869 11.0222 60.4494 10.9925 60.4066 10.972C60.3639 10.9516 60.3171 10.941 60.2697 10.9409L57.3639 10.9434Z" fill={fill}/>
      </Fragment>
    )

    const width = logo ? '50' : '100'

    return (
      <svg width={width} height="36" viewBox={`0 0 ${width} 36`} fill="none" xmlns="http://www.w3.org/2000/svg">
        <rect width={width} height="36" fill="black" fillOpacity="0"/>
        {vtex}
        <path d="M39.3559 0H7.58867C5.12544 0 3.54811 2.59188 4.70074 4.7466L7.87832 10.7021H2.11774C1.75293 10.7022 1.39433 10.7956 1.07667 10.9732C0.759019 11.1507 0.493077 11.4065 0.304605 11.7156C0.116133 12.0248 0.0115195 12.3769 0.000898204 12.7378C-0.00972314 13.0987 0.0740067 13.4562 0.243979 13.7757L10.4647 32.9227C10.6449 33.2595 10.9144 33.5412 11.2442 33.7378C11.5741 33.9343 11.9518 34.0381 12.3368 34.0381C12.7218 34.0381 13.0995 33.9343 13.4293 33.7378C13.7592 33.5412 14.0287 33.2595 14.2088 32.9227L16.9846 27.7507L20.4672 34.2762C21.6928 36.5714 25.0131 36.5756 26.243 34.283L42.1657 4.62638C43.2912 2.52883 41.7555 0 39.3559 0ZM25.0862 12.6711L18.2205 25.4615C18.1005 25.6854 17.9212 25.8728 17.7017 26.0034C17.4823 26.1341 17.231 26.2032 16.9749 26.2032C16.7188 26.2032 16.4675 26.1341 16.2481 26.0034C16.0286 25.8728 15.8492 25.6854 15.7292 25.4615L8.92986 12.7249C8.81622 12.5125 8.7599 12.2747 8.76636 12.0345C8.77283 11.7943 8.84185 11.5598 8.96675 11.3537C9.09166 11.1476 9.2682 10.977 9.4793 10.8582C9.69039 10.7395 9.92888 10.6768 10.1717 10.6761H23.8749C24.1116 10.6761 24.3443 10.7367 24.5503 10.8521C24.7564 10.9675 24.9287 11.1336 25.0507 11.3345C25.1726 11.5353 25.2399 11.7639 25.2462 11.9981C25.2524 12.2323 25.1973 12.4642 25.0862 12.6711Z" fill={fill}/>
      </svg>

    )
  }
}

export default VtexIcon

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/UserIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'

class UserIcon extends Component {
  public render() {
    return (
      <svg width="16" height="16" viewBox="0 0 1792 1792">
        <path d="M1536 1399q0 109-62.5 187t-150.5 78h-854q-88 0-150.5-78t-62.5-187q0-85 8.5-160.5t31.5-152 58.5-131 94-89 134.5-34.5q131 128 313 128t313-128q76 0 134.5 34.5t94 89 58.5 131 31.5 152 8.5 160.5zm-256-887q0 159-112.5 271.5t-271.5 112.5-271.5-112.5-112.5-271.5 112.5-271.5 271.5-112.5 271.5 112.5 112.5 271.5z" />
      </svg>
    )
  }
}

export default UserIcon
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/LogoutIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'

class GithubIcon extends Component {
  public render() {
    return (
      <svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
        <rect width="15" height="14" fill="black" fillOpacity="0" transform="translate(1 1)"/>
        <path d="M6 8H16" stroke="#134CD8" strokeMiterlimit="10" strokeLinecap="round" strokeLinejoin="round"/>
        <path d="M12 4L16 8L12 12" stroke="#134CD8" strokeMiterlimit="10" strokeLinecap="round" strokeLinejoin="round"/>
        <path d="M9 15H2C1.448 15 1 14.552 1 14V2C1 1.448 1.448 1 2 1H9" stroke="#134CD8" strokeMiterlimit="10" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>

    )
  }
}

export default GithubIcon
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of formula/react/icons/GithubIcon.tsx from the formula VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { Component } from 'react'

class GithubIcon extends Component {
  public render() {
    return (
      <svg width="15px" height="15px" viewBox="0 0 256 250">
        <g>
          <path d="M128.00106,0 C57.3172926,0 0,57.3066942 0,128.00106 C0,184.555281 36.6761997,232.535542 87.534937,249.460899 C93.9320223,250.645779 96.280588,246.684165 96.280588,243.303333 C96.280588,240.251045 96.1618878,230.167899 96.106777,219.472176 C60.4967585,227.215235 52.9826207,204.369712 52.9826207,204.369712 C47.1599584,189.574598 38.770408,185.640538 38.770408,185.640538 C27.1568785,177.696113 39.6458206,177.859325 39.6458206,177.859325 C52.4993419,178.762293 59.267365,191.04987 59.267365,191.04987 C70.6837675,210.618423 89.2115753,204.961093 96.5158685,201.690482 C97.6647155,193.417512 100.981959,187.77078 104.642583,184.574357 C76.211799,181.33766 46.324819,170.362144 46.324819,121.315702 C46.324819,107.340889 51.3250588,95.9223682 59.5132437,86.9583937 C58.1842268,83.7344152 53.8029229,70.715562 60.7532354,53.0843636 C60.7532354,53.0843636 71.5019501,49.6441813 95.9626412,66.2049595 C106.172967,63.368876 117.123047,61.9465949 128.00106,61.8978432 C138.879073,61.9465949 149.837632,63.368876 160.067033,66.2049595 C184.49805,49.6441813 195.231926,53.0843636 195.231926,53.0843636 C202.199197,70.715562 197.815773,83.7344152 196.486756,86.9583937 C204.694018,95.9223682 209.660343,107.340889 209.660343,121.315702 C209.660343,170.478725 179.716133,181.303747 151.213281,184.472614 C155.80443,188.444828 159.895342,196.234518 159.895342,208.176593 C159.895342,225.303317 159.746968,239.087361 159.746968,243.303333 C159.746968,246.709601 162.05102,250.70089 168.53925,249.443941 C219.370432,232.499507 256,184.536204 256,128.00106 C256,57.3066942 198.691187,0 128.00106,0 Z M47.9405593,182.340212 C47.6586465,182.976105 46.6581745,183.166873 45.7467277,182.730227 C44.8183235,182.312656 44.2968914,181.445722 44.5978808,180.80771 C44.8734344,180.152739 45.876026,179.97045 46.8023103,180.409216 C47.7328342,180.826786 48.2627451,181.702199 47.9405593,182.340212 Z M54.2367892,187.958254 C53.6263318,188.524199 52.4329723,188.261363 51.6232682,187.366874 C50.7860088,186.474504 50.6291553,185.281144 51.2480912,184.70672 C51.8776254,184.140775 53.0349512,184.405731 53.8743302,185.298101 C54.7115892,186.201069 54.8748019,187.38595 54.2367892,187.958254 Z M58.5562413,195.146347 C57.7719732,195.691096 56.4895886,195.180261 55.6968417,194.042013 C54.9125733,192.903764 54.9125733,191.538713 55.713799,190.991845 C56.5086651,190.444977 57.7719732,190.936735 58.5753181,192.066505 C59.3574669,193.22383 59.3574669,194.58888 58.5562413,195.146347 Z M65.8613592,203.471174 C65.1597571,204.244846 63.6654083,204.03712 62.5716717,202.981538 C61.4524999,201.94927 61.1409122,200.484596 61.8446341,199.710926 C62.5547146,198.935137 64.0575422,199.15346 65.1597571,200.200564 C66.2704506,201.230712 66.6095936,202.705984 65.8613592,203.471174 Z M75.3025151,206.281542 C74.9930474,207.284134 73.553809,207.739857 72.1039724,207.313809 C70.6562556,206.875043 69.7087748,205.700761 70.0012857,204.687571 C70.302275,203.678621 71.7478721,203.20382 73.2083069,203.659543 C74.6539041,204.09619 75.6035048,205.261994 75.3025151,206.281542 Z M86.046947,207.473627 C86.0829806,208.529209 84.8535871,209.404622 83.3316829,209.4237 C81.8013,209.457614 80.563428,208.603398 80.5464708,207.564772 C80.5464708,206.498591 81.7483088,205.631657 83.2786917,205.606221 C84.8005962,205.576546 86.046947,206.424403 86.046947,207.473627 Z M96.6021471,207.069023 C96.7844366,208.099171 95.7267341,209.156872 94.215428,209.438785 C92.7295577,209.710099 91.3539086,209.074206 91.1652603,208.052538 C90.9808515,206.996955 92.0576306,205.939253 93.5413813,205.66582 C95.054807,205.402984 96.4092596,206.021919 96.6021471,207.069023 Z" fill="#161614"></path>
        </g>
      </svg>
    )
  }
}

export default GithubIcon
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/messages/en.json from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "numberOfReviews": "{number, plural, =0 {No Reviews} =1 {# Review} other {# Reviews}}",
  "writeAReview": "{number, plural, =0 {Write the first review} other {Write a review}}",
  "rating": "{rating} out of 5 stars"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/messages/context.json from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "numberOfReviews": "# Reviews",
  "writeAReview": "Write a review",
  "rating": "Rating out of 5 stars"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/docs/README.md from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```markdown
# VTEX IO Base Component

This demo component shows you how to make a simple yet complete VTEX IO component.

It shows a simple demonstration of the following features:

- Declaring a component interface in `store/interfaces.json`.
- Declaring a schema to receive props via Storefront.
- Using the `messages` feature to have localized strings.
- Using an NPM package like `react-intl`
- Using another VTEX IO App like `vtex.styleguide`.
- Using CSS Modules to make your component customizable via CSS on a store theme.
- Using tachyons tokens to quickly style your components.
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/styles.css from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```css
.star--filled {
  color: #fc0;
}

.star--empty {
  color: #eee;
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/WriteAReview.test.tsx from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render } from '@vtex/test-tools/react'
import WriteAReview from './WriteAReview'

test("should render when there's zero", () => {
  const { getByText } = render(<WriteAReview number={0} linkTo="#foo" />)

  expect(getByText('Write the first review')).toBeTruthy()
})

test("should render when there's reviews", () => {
  const { getByText } = render(<WriteAReview number={1} linkTo="#foo" />)

  expect(getByText('Write a review')).toBeTruthy()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/WriteAReview.tsx from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { FormattedMessage } from 'react-intl'
import { Link, useOwnerBlockCssHandles } from 'vtex.render-runtime'

const handleNames = ['writeAReview']

const WriteAReview: FunctionComponent<Props> = ({ number, linkTo }) => {
  const handles = useOwnerBlockCssHandles(handleNames)

  return (
    <Link
      to={linkTo || '#reviews'}
      className={`${handles.writeAReview} c-link t-small`}
    >
      <FormattedMessage id="writeAReview" values={{ number }} />
    </Link>
  )
}

interface Props {
  number: number
  linkTo: string
}

export default WriteAReview

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/package.json from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "test": "vtex-test-tools test",
    "lint": "tsc --noEmit && eslint --ext ts,tsx ."
  },
  "dependencies": {
    "@vtex/css-handles": "^1.0.0",
    "classnames": "^2.2.6",
    "ramda": "^0.26.1",
    "react": "^16.8.3",
    "react-dom": "^16.8.3",
    "react-intl": "^2.7.2"
  },
  "devDependencies": {
    "@types/classnames": "^2.2.7",
    "@types/graphql": "^14.2.0",
    "@types/jest": "^24.0.11",
    "@types/node": "^11.13.0",
    "@types/prop-types": "^15.7.0",
    "@types/ramda": "^0.26.5",
    "@types/react": "^16.8.10",
    "@types/react-intl": "^2.3.17",
    "@vtex/test-tools": "^0.3.2",
    "apollo-client": "^2.5.1",
    "eslint": "^5.16.0",
    "eslint-config-vtex-react": "^4.1.0",
    "prettier": "^1.18.2",
    "tslint-eslint-rules": "^5.4.0",
    "typescript": "3.5.2"
  },
  "version": "0.1.0"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/Stars.test.tsx from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render } from '@vtex/test-tools/react'
import Stars from './Stars'

test('should render stars', () => {
  const { container, rerender } = render(<Stars rating={0} />)
  let empty = container.querySelectorAll('.star--empty')
  expect(empty).toHaveLength(5)

  rerender(<Stars rating={1} />)
  let filled = container.querySelectorAll('.star--filled')
  empty = container.querySelectorAll('.star--empty')
  expect(filled).toHaveLength(1)
  expect(empty).toHaveLength(4)

  rerender(<Stars rating={2} />)
  filled = container.querySelectorAll('.star--filled')
  empty = container.querySelectorAll('.star--empty')
  expect(filled).toHaveLength(2)
  expect(empty).toHaveLength(3)

  rerender(<Stars rating={3} />)
  filled = container.querySelectorAll('.star--filled')
  empty = container.querySelectorAll('.star--empty')
  expect(filled).toHaveLength(3)
  expect(empty).toHaveLength(2)

  rerender(<Stars rating={4} />)
  filled = container.querySelectorAll('.star--filled')
  empty = container.querySelectorAll('.star--empty')
  expect(filled).toHaveLength(4)
  expect(empty).toHaveLength(1)

  rerender(<Stars rating={5} />)
  filled = container.querySelectorAll('.star--filled')
  empty = container.querySelectorAll('.star--empty')
  expect(filled).toHaveLength(5)
  expect(empty).toHaveLength(0)
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/NumberOfReviews.tsx from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { FormattedMessage } from 'react-intl'
import { Link, useOwnerBlockCssHandles } from 'vtex.render-runtime'

const handleNames = ['numberOfReviews', 'numberOfReviews--zero']

const NumberOfReviews: FunctionComponent<NumberOfReviewsProps> = ({
  number,
  linkTo,
}) => {
  const handles = useOwnerBlockCssHandles(handleNames)

  if (number === 0) {
    return (
      <span
        className={`${handles.numberOfReviews} ${handles['numberOfReviews--zero']} c-muted-2 t-small`}
      >
        <FormattedMessage id="numberOfReviews" values={{ number }} />
      </span>
    )
  }

  return (
    <Link
      to={linkTo || '#reviews'}
      className={`${handles.numberOfReviews} c-link t-small`}
    >
      <FormattedMessage id="numberOfReviews" values={{ number }} />
    </Link>
  )
}

interface NumberOfReviewsProps {
  number: number
  linkTo: string
}

export default NumberOfReviews

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/NumberOfReviews.test.tsx from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render } from '@vtex/test-tools/react'
import NumberOfReviews from './NumberOfReviews'

test("should render when there's zero", () => {
  const { getByText } = render(<NumberOfReviews number={0} linkTo="#foo" />)

  expect(getByText('No Reviews')).toBeTruthy()
})

test("should render when there's reviews", () => {
  const { getByText, rerender } = render(
    <NumberOfReviews number={1} linkTo="#foo" />
  )

  expect(getByText('1 Review')).toBeTruthy()

  rerender(<NumberOfReviews number={2} linkTo="#foo" />)

  expect(getByText('2 Reviews')).toBeTruthy()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/Stars.tsx from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent, useMemo } from 'react'
import { injectIntl, InjectedIntlProps, defineMessages } from 'react-intl'
import { useOwnerBlockCssHandles } from 'vtex.render-runtime'
import Star from './components/Star'

const handleNames = ['stars']

const messages = defineMessages({
  rating: {
    id: 'rating',
    defaultMessage: '',
  },
})

const Stars: FunctionComponent<StarsProps & InjectedIntlProps> = ({
  rating,
  intl,
}) => {
  const styles = useOwnerBlockCssHandles(handleNames)
  const stars = useMemo(
    () => [null, null, null, null, null].map((_, index) => index < rating),
    [rating]
  )

  return (
    <span
      className={styles.stars}
      title={intl.formatMessage(messages.rating, { rating })}
    >
      {stars.map((value, index) => (
        <Star key={index} filled={value} />
      ))}
    </span>
  )
}

interface StarsProps {
  rating: number
}

export default injectIntl(Stars)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/store/interfaces.json from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "base-store-component": {
    "component": "Example"
  }
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/typings/storefront.d.ts from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { FunctionComponent } from 'react'

declare global {
  interface StorefrontFunctionComponent<P = {}> extends FunctionComponent<P> {
    getSchema?(props: P): object
    schema?: object
  }

  interface StorefrontComponent<P = {}, S = {}> extends Component<P, S> {
    getSchema?(props: P): object
    schema: object
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/typings/vtex.render-runtime.d.ts from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```typescript
/* Typings for `render-runtime` */
declare module 'vtex.render-runtime' {
  import { Component, ComponentType, ReactElement, ReactType } from 'react'

  export interface NavigationOptions {
    page: string
    params?: any
  }

  export interface RenderContextProps {
    runtime: {
      navigate: (options: NavigationOptions) => void
    }
  }

  interface ExtensionPointProps {
    id: string
    [key: string]: any
  }

  export const ExtensionPoint: ComponentType<ExtensionPointProps>

  interface ChildBlockProps {
    id: string
  }

  export const ChildBlock: ComponentType<ChildBlockProps>
  export const useChildBlock = function({ id: string }): object {}

  interface CssHandles {
    [key: string]: string
  }

  export const useOwnerBlockCssHandles = (handles: string[]) => CssHandles
  export const Helmet: ReactElement
  export const Link: ReactType
  export const NoSSR: ReactElement
  export const RenderContextConsumer: ReactElement
  export const canUseDOM: boolean
  export const withRuntimeContext: <TOriginalProps extends {}>(
    Component: ComponentType<TOriginalProps & RenderContextProps>
  ) => ComponentType<TOriginalProps>
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/typings/vtex.store-icons.d.ts from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.store-icons' {
  import { ComponentType } from 'react'

  export const IconStar: ComponentType
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/typings/css.d.ts from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.css' {
  const css: any
  export default css
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/typings/graphql.d.ts from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.graphql' {
  import { DocumentNode } from 'graphql'

  const value: DocumentNode
  export default value
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/typings/vtex.styleguide.d.ts from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module 'vtex.styleguide' {
  import { ComponentType } from 'react'

  export const Input: ComponentType<InputProps>

  interface InputProps {
    [key: string]: any
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of product-review-commons/react/components/Star.tsx from the product-review-commons VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { FunctionComponent } from 'react'
import { useOwnerBlockCssHandles } from 'vtex.render-runtime'
import { IconStar } from 'vtex.store-icons'
import styles from '../styles.css'
import classNames from 'classnames'

const handleNames = ['star', 'star--filled', 'star--empty']

const Star: FunctionComponent<StarProps> = ({ filled }) => {
  const handles = useOwnerBlockCssHandles(handleNames)

  return (
    <span
      className={classNames(handles.star, {
        [`${styles['star--filled']} ${handles['star--filled']}`]: filled,
        [`${styles['star--empty']} ${handles['star--empty']}`]: !filled,
      })}
    >
      <IconStar />
    </span>
  )
}

interface StarProps {
  filled: boolean
}

export default Star

```