From ecef9b834a8290203fda87717e541473acdb0f94 Mon Sep 17 00:00:00 2001 From: Luis Felipe Date: Wed, 28 Aug 2024 21:15:13 -0300 Subject: [PATCH 01/26] feat: add register hero section --- src/App.tsx | 2 + .../register/components/Hero/Hero.module.scss | 84 +++++++++++++++++++ .../register/components/Hero/Hero.spec.tsx | 49 +++++++++++ .../register/components/Hero/Hero.stories.tsx | 9 ++ src/pages/register/components/Hero/Hero.tsx | 37 ++++++++ .../register/components/Hero/images/octo.svg | 31 +++++++ .../components/Hero/images/octopost.svg | 10 +++ src/pages/register/home.module.scss | 57 +++++++++++++ src/pages/register/register.tsx | 18 ++++ 9 files changed, 297 insertions(+) create mode 100644 src/pages/register/components/Hero/Hero.module.scss create mode 100644 src/pages/register/components/Hero/Hero.spec.tsx create mode 100644 src/pages/register/components/Hero/Hero.stories.tsx create mode 100644 src/pages/register/components/Hero/Hero.tsx create mode 100644 src/pages/register/components/Hero/images/octo.svg create mode 100644 src/pages/register/components/Hero/images/octopost.svg create mode 100644 src/pages/register/home.module.scss create mode 100644 src/pages/register/register.tsx diff --git a/src/App.tsx b/src/App.tsx index 681fbf62a..d36b76f06 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,6 +4,7 @@ import { HashRouter as Router, Route } from 'react-router-dom'; import { ErrorBoundary } from '@sentry/react'; import Home from './pages/home/home'; +import Register from './pages/register/register'; import SentryRoutes from '~components/SentrySetup/SentrySetup'; @@ -17,6 +18,7 @@ function App(): ReactNode { } path="/" /> + } path="/register" /> diff --git a/src/pages/register/components/Hero/Hero.module.scss b/src/pages/register/components/Hero/Hero.module.scss new file mode 100644 index 000000000..b972e7bfd --- /dev/null +++ b/src/pages/register/components/Hero/Hero.module.scss @@ -0,0 +1,84 @@ +@use '~styles/breakpoints.scss' as *; +@use '~styles/global.scss' as *; + +.main { + width: 100%; + + display: grid; + + background: linear-gradient(0deg, #894df6, #894df6), + linear-gradient( + 109.54deg, + rgba(123, 80, 255, 0.2) 0%, + rgba(81, 202, 212, 0.2) 100% + ); +} + +.header { + width: 100%; + + display: flex; + + align-items: center; + justify-content: space-between; + + padding: 1.5rem 2rem; +} + +.signin { + width: 92px; + height: 40px; + + color: #fff; + text-align: center; + font-size: 14px; + font-weight: 500; + line-height: 20px; + + padding: 0.625rem 1.5rem; + border: 1px solid #fff; + + border-radius: 100px; + letter-spacing: 0.1px; +} + +.hero { + width: 100%; + + display: flex; + + flex-direction: column; + gap: 4px; + + align-items: flex-end; + + color: #fff; + + text-align: right; + + padding: 1.5rem; + + .title { + font-size: 36px; + font-weight: 700; + line-height: 44px; + + margin: 0; + } + + .description { + font-size: 16px; + font-weight: 400; + line-height: 24px; + + margin: 0; + letter-spacing: 0.5px; + } +} + +.octo { + width: 100%; + + display: flex; + flex-direction: column; +} diff --git a/src/pages/register/components/Hero/Hero.spec.tsx b/src/pages/register/components/Hero/Hero.spec.tsx new file mode 100644 index 000000000..afcc3d1f9 --- /dev/null +++ b/src/pages/register/components/Hero/Hero.spec.tsx @@ -0,0 +1,49 @@ +import { useNavigate } from 'react-router-dom'; + +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import Hero from './Hero'; + +vi.mock('react-router-dom', () => ({ + useNavigate: vi.fn(() => ({ + navigate: vi.fn(), + })), +})); + +const useNavigateMock = vi.mocked(useNavigate); + +describe('Hero component', () => { + describe('show the content on screen', () => { + it('renders its content', () => { + render(); + + const octopostLogo = screen.getByLabelText('octopost logo'); + const signInButton = screen.getByText('Sign in'); + const title = screen.getByText('New here?'); + const description = screen.getByText( + /welcome to octopost. enter your personal/i + ); + const octopostIcon = screen.getByTestId('octopost-icon'); + + expect(octopostLogo).toBeInTheDocument(); + expect(signInButton).toBeInTheDocument(); + expect(title).toBeInTheDocument(); + expect(description).toBeInTheDocument(); + expect(octopostIcon).toBeInTheDocument(); + }); + it('change page on SignIn click', async () => { + const navigateMock = vi.fn(); + + useNavigateMock.mockReturnValue(navigateMock); + + render(); + + const signInButton = screen.getByText('Sign in'); + + await userEvent.click(signInButton); + + expect(navigateMock).toHaveBeenCalledWith('/create'); + }); + }); +}); diff --git a/src/pages/register/components/Hero/Hero.stories.tsx b/src/pages/register/components/Hero/Hero.stories.tsx new file mode 100644 index 000000000..d162ccbf6 --- /dev/null +++ b/src/pages/register/components/Hero/Hero.stories.tsx @@ -0,0 +1,9 @@ +import { Story } from '@ladle/react'; + +import Hero from './Hero'; + +export const HeroStories: Story = () => ( +
+ +
+); diff --git a/src/pages/register/components/Hero/Hero.tsx b/src/pages/register/components/Hero/Hero.tsx new file mode 100644 index 000000000..69ee28d9c --- /dev/null +++ b/src/pages/register/components/Hero/Hero.tsx @@ -0,0 +1,37 @@ +import { ReactNode } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import scss from './Hero.module.scss'; + +import Octo from './images/octo.svg?react'; +import OctopostLogo from './images/octopost.svg?react'; + +function Hero(): ReactNode { + const navigate = useNavigate(); + + return ( +
+
+ + + + +
+
+

New here?

+

+ Welcome to Octopost. Enter your personal +
+ details and start your journey with us +

+
+
+ +
+
+ ); +} + +export default Hero; diff --git a/src/pages/register/components/Hero/images/octo.svg b/src/pages/register/components/Hero/images/octo.svg new file mode 100644 index 000000000..b7c7cb566 --- /dev/null +++ b/src/pages/register/components/Hero/images/octo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/pages/register/components/Hero/images/octopost.svg b/src/pages/register/components/Hero/images/octopost.svg new file mode 100644 index 000000000..03e897166 --- /dev/null +++ b/src/pages/register/components/Hero/images/octopost.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/pages/register/home.module.scss b/src/pages/register/home.module.scss new file mode 100644 index 000000000..71df7217f --- /dev/null +++ b/src/pages/register/home.module.scss @@ -0,0 +1,57 @@ +@use '~styles/breakpoints.scss' as *; + +.content { + overflow: hidden; + + display: grid; + grid-template-areas: + 'header' + 'actions' + 'aside' + 'editor'; + + grid-template-columns: 100vw; + + .aside { + grid-area: aside; + } + + .editor { + overflow-x: hidden; + + grid-area: editor; + } + + .editor { + > :first-child { + display: none; + } + } + + .actions { + grid-area: actions; + } +} + +@include from905 { + .content { + width: 90%; + max-width: 128rem; + + grid-template-areas: + 'aside editor' + 'aside actions'; + grid-template-columns: 30rem 1fr; + gap: 2.4rem; + + margin: 0 auto; + } + + .content { + .editor { + > :first-child { + display: flex; + } + } + } +} diff --git a/src/pages/register/register.tsx b/src/pages/register/register.tsx new file mode 100644 index 000000000..deafc7f1d --- /dev/null +++ b/src/pages/register/register.tsx @@ -0,0 +1,18 @@ +import { ReactNode } from 'react'; + +import Hero from './components/Hero/Hero'; + +import scss from './home.module.scss'; + +function Home(): ReactNode { + return ( + <> +
+ +
+
+ + ); +} + +export default Home; From 5e27c2ea61b0047377603d39515b83fa213e5955 Mon Sep 17 00:00:00 2001 From: Luis Felipe Date: Thu, 29 Aug 2024 19:14:59 -0300 Subject: [PATCH 02/26] feat: add text input --- package.json | 1 + pnpm-lock.yaml | 12 ++ .../TextInput/TextInput.module.scss | 112 ++++++++++++++++++ src/components/TextInput/TextInput.spec.tsx | 64 ++++++++++ .../TextInput/TextInput.stories.tsx | 23 ++++ src/components/TextInput/TextInput.tsx | 78 ++++++++++++ src/components/TextInput/TextInput.types.ts | 9 ++ src/components/TextInput/assets/alertIcon.svg | 3 + 8 files changed, 302 insertions(+) create mode 100644 src/components/TextInput/TextInput.module.scss create mode 100644 src/components/TextInput/TextInput.spec.tsx create mode 100644 src/components/TextInput/TextInput.stories.tsx create mode 100644 src/components/TextInput/TextInput.tsx create mode 100644 src/components/TextInput/TextInput.types.ts create mode 100644 src/components/TextInput/assets/alertIcon.svg diff --git a/package.json b/package.json index 538e8aaf0..85e899a53 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "normalize.css": "8.0.1", "react": "18.2.0", "react-dom": "18.2.0", + "react-hook-form": "7.53.0", "react-i18next": "13.5.0", "react-router-dom": "6.22.1", "zustand": "4.5.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44db68a51..4fb737286 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,6 +56,9 @@ dependencies: react-dom: specifier: 18.2.0 version: 18.2.0(react@18.2.0) + react-hook-form: + specifier: 7.53.0 + version: 7.53.0(react@18.2.0) react-i18next: specifier: 13.5.0 version: 13.5.0(i18next@23.9.0)(react-dom@18.2.0)(react@18.2.0) @@ -10519,6 +10522,15 @@ packages: react: 18.2.0 scheduler: 0.23.2 + /react-hook-form@7.53.0(react@18.2.0): + resolution: {integrity: sha512-M1n3HhqCww6S2hxLxciEXy2oISPnAzxY7gvwVPrtlczTM/1dDadXgUxDpHMrMTblDOcm/AXtXxHwZ3jpg1mqKQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + dependencies: + react: 18.2.0 + dev: false + /react-hotkeys-hook@4.5.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Samb85GSgAWFQNvVt3PS90LPPGSf9mkH/r4au81ZP1yOIFayLC3QAvqTgGtJ8YEDMXtPmaVBs6NgipHO6h4Mug==} peerDependencies: diff --git a/src/components/TextInput/TextInput.module.scss b/src/components/TextInput/TextInput.module.scss new file mode 100644 index 000000000..5f8da634e --- /dev/null +++ b/src/components/TextInput/TextInput.module.scss @@ -0,0 +1,112 @@ +@use '../../styles/global'; +@use '~styles/breakpoints.scss' as *; + +@mixin apply-color($color) { + &.containerFocus { + color: $color; + } + + .inputWrapper { + .label { + &.labelAnimate { + color: $color; + } + } + } +} + +.container { + &.containerError { + color: global.$secondaryRed; + } + + &.containerFocus { + color: global.$secondaryPurple; + } + + .input { + width: 100%; + + font-size: 1rem; + font-weight: 400; + + border: 0; + letter-spacing: 0.03rem; + + &.inputFocus { + caret-color: global.$secondaryPurple; + } + + &.inputError { + caret-color: global.$secondaryRed; + } + + &:focus { + outline: none; + } + } + + .fieldset { + display: flex; + + justify-content: space-between; + + margin: 0; + padding: 1rem; + border: 1px solid #7a757f; + + border-radius: 4px; + + &.fieldsetFocus { + border: 2px solid global.$secondaryPurple; + } + + &.fieldsetError { + border: 2px solid global.$secondaryRed; + } + } + + .legend { + font-size: 0.75rem; + font-weight: 400; + line-height: 0; + + padding: 0 0.25rem; + } + + .rightIcon { + width: 1.5rem; + + display: flex; + + align-items: center; + + &:hover { + cursor: pointer; + } + + &.rightIconError { + color: global.$secondaryRed; + } + } + + .supportText { + height: 1.5rem; + + color: global.$secondaryGray; + font-size: 0.75rem; + font-weight: 400; + + padding: 0.25rem 1rem; + + visibility: hidden; + + &.supportTextExists { + visibility: visible; + } + + &.supportTextError { + color: global.$secondaryRed; + } + } +} diff --git a/src/components/TextInput/TextInput.spec.tsx b/src/components/TextInput/TextInput.spec.tsx new file mode 100644 index 000000000..14cdf4a43 --- /dev/null +++ b/src/components/TextInput/TextInput.spec.tsx @@ -0,0 +1,64 @@ +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import TextInput from './TextInput'; + +const mockProps = { + error: false, + handleClear: vi.fn(), + label: 'Test Label', + name: 'testInput', + onChange: vi.fn(), + onFocus: vi.fn(), + placeholder: 'Test Placeholder', + readonly: false, + required: false, + setValue: vi.fn(), + supportText: 'Test Error Message', + type: 'text', + value: 'Value', +}; + +describe('TextInput component', () => { + let user = userEvent.setup(); + + beforeEach(() => { + user = userEvent.setup(); + }); + + it('renders the component', () => { + render(); + + const inputElement = screen.getByPlaceholderText('Test Placeholder'); + const labelElement = screen.getByText('Test Label'); + + expect(inputElement).toBeInTheDocument(); + expect(labelElement).toBeInTheDocument(); + }); + + it('handles input value correctly', async () => { + render(); + + const inputElement = screen.getByPlaceholderText('Test Placeholder'); + + await user.type(inputElement, 'value'); + + expect(inputElement).toHaveValue('value'); + }); + + it('handles onFocus callback', async () => { + render(); + const inputElement = screen.getByPlaceholderText('Test Placeholder'); + + await userEvent.click(inputElement); + + expect(mockProps.onFocus).toHaveBeenCalled(); + }); + + it('displays error message when errors prop is true', () => { + render(); + + const errorMessage = screen.getByText('Test Error Message'); + expect(errorMessage).toBeInTheDocument(); + }); +}); diff --git a/src/components/TextInput/TextInput.stories.tsx b/src/components/TextInput/TextInput.stories.tsx new file mode 100644 index 000000000..c9b40e6cc --- /dev/null +++ b/src/components/TextInput/TextInput.stories.tsx @@ -0,0 +1,23 @@ +import { Story } from '@ladle/react'; + +import TextInput from './TextInput'; + +import { TInputProps } from './TextInput.types'; + +export default { + component: TextInput, + title: 'TextInput', +}; + +const Template: Story = (args) => ( + +); + +export const InputSearchComponent = Template.bind({}); +InputSearchComponent.args = { + error: false, + name: 'Input Search', + placeholder: 'Search Social Media', + required: true, + supportText: 'Erro no campo de entrada', +}; diff --git a/src/components/TextInput/TextInput.tsx b/src/components/TextInput/TextInput.tsx new file mode 100644 index 000000000..c1f8c89a1 --- /dev/null +++ b/src/components/TextInput/TextInput.tsx @@ -0,0 +1,78 @@ +import { FocusEvent, forwardRef, ReactNode, useState } from 'react'; + +import classNames from 'classnames'; + +import Icon from '~components/Icon/Icon'; + +import scss from './TextInput.module.scss'; + +import { TInputProps } from './TextInput.types'; + +function TextInput(props: TInputProps): ReactNode { + const inputClass = [scss.input]; + const legendClass = [scss.legend]; + const fieldsetClass = [scss.fieldset]; + const containerClass = [scss.container]; + const supportTextClass = [scss.supportText]; + const rightIconClass = [scss.rightIcon]; + + const [isFocused, setIsFocused] = useState(false); + + if (props.error) { + fieldsetClass.push(scss.fieldsetError); + containerClass.push(scss.containerError); + rightIconClass.push(scss.rightIconError); + supportTextClass.push(scss.supportTextError); + inputClass.push(scss.inputError); + } + + if (isFocused && !props.error) { + fieldsetClass.push(scss.fieldsetFocus); + containerClass.push(scss.containerFocus); + inputClass.push(scss.inputFocus); + } + + if (props.supportText) { + supportTextClass.push(scss.supportTextExists); + } + + const onInputFocus = (event: FocusEvent): void => { + if (props.onFocus) props.onFocus(event); + setIsFocused(true); + }; + + const onInputBlur = (e: FocusEvent): void => { + setIsFocused(e.target.value.length > 0); + }; + + return ( +
+ +
{props.supportText}
+
+ ); +} + +const ForwardedInputSearch = forwardRef(TextInput); +export default ForwardedInputSearch; diff --git a/src/components/TextInput/TextInput.types.ts b/src/components/TextInput/TextInput.types.ts new file mode 100644 index 000000000..3631c96cb --- /dev/null +++ b/src/components/TextInput/TextInput.types.ts @@ -0,0 +1,9 @@ +import { HTMLProps, ReactElement } from 'react'; + +type HtmlInputProps = Omit, 'onChange'>; + +export type TInputProps = HtmlInputProps & { + error?: boolean; + rightIcon?: ReactElement; + supportText?: string; +}; diff --git a/src/components/TextInput/assets/alertIcon.svg b/src/components/TextInput/assets/alertIcon.svg new file mode 100644 index 000000000..2a585dcd8 --- /dev/null +++ b/src/components/TextInput/assets/alertIcon.svg @@ -0,0 +1,3 @@ + + + From 8bf74c261ad531aa0a5dc2e323f5610168a1a561 Mon Sep 17 00:00:00 2001 From: Luis Felipe Date: Fri, 30 Aug 2024 00:17:22 -0300 Subject: [PATCH 03/26] feat: add mobile register screen --- package.json | 2 + pnpm-lock.yaml | 18 ++++ src/components/Icon/data.ts | 10 +++ src/components/Icon/icons/blind-eye.svg | 4 + src/components/Icon/icons/instagram.svg | 3 + src/components/Icon/icons/letter.svg | 3 + src/components/Icon/icons/tiktok.svg | 3 + src/components/Icon/icons/twitter.svg | 3 + .../components/Footer/Footer.module.scss | 23 +++++ .../components/Footer/Footer.spec.tsx | 35 ++++++++ .../components/Footer/Footer.stories.tsx | 9 ++ .../register/components/Footer/Footer.tsx | 16 ++++ src/pages/register/components/Form/Form.tsx | 87 +++++++++++++++++++ .../register/components/Form/Hero.module.scss | 18 ++++ .../register/components/Form/Hero.spec.tsx | 49 +++++++++++ .../register/components/Form/Hero.stories.tsx | 9 ++ .../register/components/Form/images/octo.svg | 31 +++++++ .../components/Form/images/octopost.svg | 10 +++ .../register/components/Hero/Hero.module.scss | 29 ++++--- .../register/components/Hero/Hero.spec.tsx | 2 +- src/pages/register/components/Hero/Hero.tsx | 19 ++-- .../register/components/Hero/images/octo.svg | 4 +- .../SocialLogin/SocialLogin.module.scss | 43 +++++++++ .../SocialLogin/SocialLogin.spec.tsx | 21 +++++ .../SocialLogin/SocialLogin.stories.tsx | 7 ++ .../components/SocialLogin/SocialLogin.tsx | 29 +++++++ src/pages/register/home.module.scss | 57 ------------ src/pages/register/register.module.scss | 5 ++ src/pages/register/register.tsx | 15 ++-- 29 files changed, 476 insertions(+), 88 deletions(-) create mode 100644 src/components/Icon/icons/blind-eye.svg create mode 100644 src/components/Icon/icons/instagram.svg create mode 100644 src/components/Icon/icons/letter.svg create mode 100644 src/components/Icon/icons/tiktok.svg create mode 100644 src/components/Icon/icons/twitter.svg create mode 100644 src/pages/register/components/Footer/Footer.module.scss create mode 100644 src/pages/register/components/Footer/Footer.spec.tsx create mode 100644 src/pages/register/components/Footer/Footer.stories.tsx create mode 100644 src/pages/register/components/Footer/Footer.tsx create mode 100644 src/pages/register/components/Form/Form.tsx create mode 100644 src/pages/register/components/Form/Hero.module.scss create mode 100644 src/pages/register/components/Form/Hero.spec.tsx create mode 100644 src/pages/register/components/Form/Hero.stories.tsx create mode 100644 src/pages/register/components/Form/images/octo.svg create mode 100644 src/pages/register/components/Form/images/octopost.svg create mode 100644 src/pages/register/components/SocialLogin/SocialLogin.module.scss create mode 100644 src/pages/register/components/SocialLogin/SocialLogin.spec.tsx create mode 100644 src/pages/register/components/SocialLogin/SocialLogin.stories.tsx create mode 100644 src/pages/register/components/SocialLogin/SocialLogin.tsx delete mode 100644 src/pages/register/home.module.scss create mode 100644 src/pages/register/register.module.scss diff --git a/package.json b/package.json index 85e899a53..d92f20c59 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "test": "vitest" }, "dependencies": { + "@hookform/resolvers": "3.9.0", "@redux-devtools/extension": "3.3.0", "@sentry/react": "7.102.0", "classnames": "2.5.1", @@ -55,6 +56,7 @@ "react-hook-form": "7.53.0", "react-i18next": "13.5.0", "react-router-dom": "6.22.1", + "zod": "3.23.8", "zustand": "4.5.1" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4fb737286..82e44f3d7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@hookform/resolvers': + specifier: 3.9.0 + version: 3.9.0(react-hook-form@7.53.0) '@redux-devtools/extension': specifier: 3.3.0 version: 3.3.0(redux@5.0.1) @@ -65,6 +68,9 @@ dependencies: react-router-dom: specifier: 6.22.1 version: 6.22.1(react-dom@18.2.0)(react@18.2.0) + zod: + specifier: 3.23.8 + version: 3.23.8 zustand: specifier: 4.5.1 version: 4.5.1(@types/react@18.2.57)(react@18.2.0) @@ -1655,6 +1661,14 @@ packages: '@hapi/hoek': 9.3.0 dev: true + /@hookform/resolvers@3.9.0(react-hook-form@7.53.0): + resolution: {integrity: sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg==} + peerDependencies: + react-hook-form: ^7.0.0 + dependencies: + react-hook-form: 7.53.0(react@18.2.0) + dev: false + /@humanwhocodes/config-array@0.11.14: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -13010,6 +13024,10 @@ packages: engines: {node: '>=12.20'} dev: true + /zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + dev: false + /zustand@4.5.1(@types/react@18.2.57)(react@18.2.0): resolution: {integrity: sha512-XlauQmH64xXSC1qGYNv00ODaQ3B+tNPoy22jv2diYiP4eoDKr9LA+Bh5Bc3gplTrFdb6JVI+N4kc1DZ/tbtfPg==} engines: {node: '>=12.7.0'} diff --git a/src/components/Icon/data.ts b/src/components/Icon/data.ts index 04c29c14c..063715872 100644 --- a/src/components/Icon/data.ts +++ b/src/components/Icon/data.ts @@ -1,11 +1,14 @@ import Alert from './icons/alert.svg?react'; import ArrowRight from './icons/arrow-right.svg?react'; +import BlindEye from './icons/blind-eye.svg?react'; import Check from './icons/check.svg?react'; import Circle from './icons/circle.svg?react'; import Close from './icons/close.svg?react'; import TriangleDropArrow from './icons/drop-down.svg?react'; import Hamburguer from './icons/hamburguer.svg?react'; +import Instagram from './icons/instagram.svg?react'; import LeftArrow from './icons/left-arrow.svg?react'; +import Letter from './icons/letter.svg?react'; import Mag from './icons/mag.svg?react'; import Minus from './icons/minus.svg?react'; import Plus from './icons/plus.svg?react'; @@ -13,16 +16,21 @@ import RightArrow from './icons/right-arrow.svg?react'; import SmallCircleFilled from './icons/small-circle-filled.svg?react'; import StarFilled from './icons/star-filled.svg?react'; import Star from './icons/star.svg?react'; +import Titktok from './icons/tiktok.svg?react'; import TriangleLeftArrow from './icons/TriangleLeftArrow.svg?react'; +import Twitter from './icons/twitter.svg?react'; export const icons = { alert: Alert, 'arrow-right': ArrowRight, + 'blind-eye': BlindEye, check: Check, circle: Circle, close: Close, hamburguer: Hamburguer, + instagram: Instagram, 'left-arrow': LeftArrow, + letter: Letter, mag: Mag, minus: Minus, plus: Plus, @@ -30,6 +38,8 @@ export const icons = { 'small-circle-filled': SmallCircleFilled, star: Star, 'star-filled': StarFilled, + titktok: Titktok, 'triangle-drop-arrow': TriangleDropArrow, 'triangle-left-arrow': TriangleLeftArrow, + twitter: Twitter, }; diff --git a/src/components/Icon/icons/blind-eye.svg b/src/components/Icon/icons/blind-eye.svg new file mode 100644 index 000000000..08ca13446 --- /dev/null +++ b/src/components/Icon/icons/blind-eye.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/Icon/icons/instagram.svg b/src/components/Icon/icons/instagram.svg new file mode 100644 index 000000000..4fed753d6 --- /dev/null +++ b/src/components/Icon/icons/instagram.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/Icon/icons/letter.svg b/src/components/Icon/icons/letter.svg new file mode 100644 index 000000000..3ccadfe57 --- /dev/null +++ b/src/components/Icon/icons/letter.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/Icon/icons/tiktok.svg b/src/components/Icon/icons/tiktok.svg new file mode 100644 index 000000000..b3bdcca1e --- /dev/null +++ b/src/components/Icon/icons/tiktok.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/Icon/icons/twitter.svg b/src/components/Icon/icons/twitter.svg new file mode 100644 index 000000000..38425f37f --- /dev/null +++ b/src/components/Icon/icons/twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/pages/register/components/Footer/Footer.module.scss b/src/pages/register/components/Footer/Footer.module.scss new file mode 100644 index 000000000..a4f3c57fd --- /dev/null +++ b/src/pages/register/components/Footer/Footer.module.scss @@ -0,0 +1,23 @@ +@use '~styles/breakpoints.scss' as *; +@use '~styles/global.scss'; + +.footer { + display: flex; + + justify-content: flex-end; + + font-size: 1rem; + + font-weight: 500; + + padding: 2rem 2rem 1rem; + + p { + color: global.$tertiaryGray; + } + + a { + color: global.$secondaryPurple; + text-decoration: none; + } +} diff --git a/src/pages/register/components/Footer/Footer.spec.tsx b/src/pages/register/components/Footer/Footer.spec.tsx new file mode 100644 index 000000000..b378f9de5 --- /dev/null +++ b/src/pages/register/components/Footer/Footer.spec.tsx @@ -0,0 +1,35 @@ +import { NavLink } from 'react-router-dom'; + +import { render, screen } from '@testing-library/react'; + +import Footer from './Footer'; + +vi.mock('react-router-dom', () => ({ + NavLink: vi.fn(({ children }) => children), +})); + +const NavLinkMocked = vi.mocked(NavLink); + +describe('Footer component', () => { + describe('show the content on screen', () => { + it('renders its content', () => { + render(