Skip to content

Commit

Permalink
Merge branch 'development' into 4267-vacancy-info-card
Browse files Browse the repository at this point in the history
  • Loading branch information
Katiene Souza committed Oct 5, 2023
2 parents bf46c57 + 4f1fc69 commit 6a0470e
Show file tree
Hide file tree
Showing 10 changed files with 269 additions and 2 deletions.
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default {
'\\.(css|less|sass|scss)$': 'identity-obj-proxy',
'^@components/(.*)$': '<rootDir>/src/components/$1',
'^@assets/(.*)$': '<rootDir>/src/assets/$1',
'^@hooks/(.*)$': '<rootDir>/src/hooks/$1',
},
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
};
1 change: 1 addition & 0 deletions src/components/InputWithIcon/InputWithIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type InputWithIconProps = {
value?: string;
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
type?: string;
name?: string;
};

const InputWithIcon = ({
Expand Down
2 changes: 1 addition & 1 deletion src/components/InputWithIcon/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const Container = styled.div`
align-items: center;
gap: 1rem;
border: 1px solid var(--gray-light);
padding: 1rem;
padding: 0.75rem;
border-radius: 0.5rem;
color: var(--purple-dark);
background-color: var(--white);
Expand Down
13 changes: 13 additions & 0 deletions src/components/SearchBar/SearchBar.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import SearchBar from './SearchBar';

describe('<SearchBar />', () => {
it('should not render with text "Buscas mais recentes" when search some location', () => {
cy.mount(<SearchBar />);

cy.get('input[placeholder="Localização"]').type('test');

cy.contains('Buscar vagas').click();

cy.contains('Buscas mais recentes').should('not.exist');
});
});
78 changes: 78 additions & 0 deletions src/components/SearchBar/SearchBar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { render, screen } from '@testing-library/react';
import { expect, jest } from '@jest/globals';
import '@testing-library/jest-dom/extend-expect';
import userEvent from '@testing-library/user-event';

import SearchBar from './SearchBar';

describe('<SearchBar />', () => {
let container: HTMLElement;

beforeEach(() => {
container = render(<SearchBar />).container;

jest.resetAllMocks();
});

it('should render the component', () => {
expect(container).toBeDefined();
});

it('should render with the text "O quê você procura?"', () => {
(expect as any)(container).toHaveTextContent('O quê você procura?');
});

it('should render with the text "Onde?"', () => {
(expect as any)(container).toHaveTextContent('Onde?');
});

it('should not render with the text "Buscas mais recentes:"', () => {
(expect as any)(container).not.toHaveTextContent('Buscas mais recentes:');
});

it('should render with text "Buscas mais recentes:" when search some tech or position', async () => {
const input = screen.getByPlaceholderText(
'Cargo, tecnologia ou palavra-chave',
);

const button = screen.getByText('Buscar vagas');

await userEvent.type(input, 'test');
await userEvent.click(button);

(expect as any)(container).toHaveTextContent('Buscas mais recentes:');
});

it('should render the recent searches when search some tech or position', async () => {
const input = screen.getByPlaceholderText(
'Cargo, tecnologia ou palavra-chave',
);

const button = screen.getByText('Buscar vagas');

await userEvent.type(input, 'test');

await userEvent.click(button);

(expect as any)(input).toHaveValue('test');
});

it('should render the text in input when click in recent search', async () => {
const input = screen.getByPlaceholderText(
'Cargo, tecnologia ou palavra-chave',
);

const button = screen.getByText('Buscar vagas');

await userEvent.type(input, 'test');
await userEvent.click(button);
await userEvent.clear(input);

const recentSearch = screen.getByText('test');

await userEvent.click(recentSearch);

(expect as any)(input).toHaveValue('test');
});
});
75 changes: 75 additions & 0 deletions src/components/SearchBar/SearchBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import Text from './../Text';
import InputWithIcon from './../InputWithIcon';
import Button from './../Button';

import useField from '@hooks/useField';
import useRecentSearches from '@hooks/useRecentSearches';

import * as S from './styles';

const SearchBar = () => {
const [location] = useField('text', 'location');
const [positionOrTech, , setPositionOrTech] = useField('text', 'magnifier');

const [recentSearches, addRecentSearch] = useRecentSearches();

const handleOnSearch = () => {
positionOrTech.value && addRecentSearch(positionOrTech.value);
};

const handleRecentSearch = (value: string) => {
setPositionOrTech(value);
};

return (
<S.Container className="search-bar">
<div className="search-form">
<div className="form-group">
<label htmlFor="magnifier">
<Text label="O quê você procura?" fontWeight="600" />
</label>
<InputWithIcon
icon="magnifier"
placeholder="Cargo, tecnologia ou palavra-chave"
{...positionOrTech}
/>
</div>
<div className="form-group">
<label htmlFor="location">
<Text label="Onde?" fontWeight="600" />
</label>
<InputWithIcon
icon="location"
placeholder="Localização"
{...location}
/>
</div>
<Button
label="Buscar vagas"
onClick={handleOnSearch}
backgroundColor="yellow"
fontWeight="600"
/>
</div>
{recentSearches && (
<div className="recent-search">
<Text label="Buscas mais recentes:" fontSize="small" />
<div className="search">
{recentSearches.map(search => (
<Button
label={search}
onClick={() => handleRecentSearch(search)}
fontSize="small"
fontColor="purple-light"
backgroundColor="white"
borderColor="purple-light"
/>
))}
</div>
</div>
)}
</S.Container>
);
};

export default SearchBar;
1 change: 1 addition & 0 deletions src/components/SearchBar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './SearchBar';
52 changes: 52 additions & 0 deletions src/components/SearchBar/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import styled from 'styled-components';

export const Container = styled.div`
display: flex;
flex-direction: column;
padding: 2rem;
background-color: var(--white);
box-shadow: 0px 1rem 2rem rgba(207.7, 207.7, 207.7, 0.2);
border-radius: 1rem;
margin: 0 8.5rem;
.search-form {
display: flex;
align-items: end;
gap: 1.5rem;
margin-bottom: 1rem;
.input-with-icon {
width: 28rem;
}
.form-group {
label {
p {
justify-content: flex-start;
margin-bottom: 0.5rem;
}
}
}
button {
padding: 0.75rem 1.4rem;
}
}
.recent-search {
display: flex;
gap: 1rem;
p {
justify-content: flex-start;
}
button {
padding: 0.625rem;
}
.search {
display: flex;
gap: 0.5rem;
}
}
`;
14 changes: 13 additions & 1 deletion src/hooks/useField.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { useState, ChangeEvent } from 'react';

const useField = (type: string, name: string) => {
type UseFieldResult = [
{
type: string;
value: string;
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
name: string;
},
() => void,
React.Dispatch<React.SetStateAction<string>>,
];

const useField = (type: string, name: string): UseFieldResult => {
const [value, setValue] = useState('');

const onChange = (event: ChangeEvent<HTMLInputElement>) => {
Expand All @@ -19,6 +30,7 @@ const useField = (type: string, name: string) => {
name,
},
reset,
setValue,
];
};

Expand Down
34 changes: 34 additions & 0 deletions src/hooks/useRecentSearches.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useState, useEffect } from 'react';

const useRecentSearches = () => {
const [recentSearches, setRecentSearch] = useState<string[] | null>(null);

const addRecentSearch = (value: string) => {
const recentSearches = localStorage.getItem('recentSearches');
const recentSearchesArray = recentSearches
? JSON.parse(recentSearches)
: [];

if (recentSearchesArray.includes(value)) return;

setRecentSearch([value, ...recentSearchesArray]);
recentSearchesArray.unshift(value);
localStorage.setItem('recentSearches', JSON.stringify(recentSearchesArray));
};

useEffect(() => {
const recentSearchesJSON = localStorage.getItem('recentSearches');
if (recentSearchesJSON) {
setRecentSearch(JSON.parse(recentSearchesJSON));
}
}, []);

useEffect(() => {
recentSearches &&
localStorage.setItem('recentSearches', JSON.stringify(recentSearches));
}, [recentSearches]);

return [recentSearches, addRecentSearch] as const;
};

export default useRecentSearches;

0 comments on commit 6a0470e

Please sign in to comment.