Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - Marketplace Pages #535

Merged
merged 34 commits into from
Sep 14, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f1c5050
Add marketplace page with its search section
LuanEdCosta Sep 2, 2021
fe813b8
Create the MarketplaceTaskItem component
LuanEdCosta Sep 2, 2021
dc64d0b
Create other MarketplaceTaskItem pieces
LuanEdCosta Sep 3, 2021
718082e
FInish marketplace initial screen
LuanEdCosta Sep 3, 2021
b2c7230
Fix marketplace search placeholder casing
LuanEdCosta Sep 3, 2021
13d2b38
Create the marketplace store with types, reducer and selectors
LuanEdCosta Sep 3, 2021
bb883e2
Create the marketplace api
LuanEdCosta Sep 3, 2021
5718c50
Create marketplace store actions with tests
LuanEdCosta Sep 3, 2021
70bbc51
Create marketplace search page basic structure
LuanEdCosta Sep 8, 2021
0669739
Create the marketplace task details page
LuanEdCosta Sep 8, 2021
f0babc0
Fix errors and implement the login in the marketplace task details page
LuanEdCosta Sep 8, 2021
86e13cc
Fix details and add skeleton for loading in the marketplace task deta…
LuanEdCosta Sep 9, 2021
bbae392
Use task category in marketplace task details changes section
LuanEdCosta Sep 9, 2021
eedc024
Format the marketplace task details changes date
LuanEdCosta Sep 9, 2021
df075d1
Create the marketplace author page
LuanEdCosta Sep 9, 2021
b15ca20
Finish marketplace author page skeletons
LuanEdCosta Sep 9, 2021
5353c81
Improve marketplace task details avatar styles
LuanEdCosta Sep 9, 2021
317e8ce
Create the marketplace search page base structure
LuanEdCosta Sep 10, 2021
6347447
Create the marketplace task item header
LuanEdCosta Sep 10, 2021
de5df8e
Open marketplae search page with filters
LuanEdCosta Sep 13, 2021
14e78bb
Create list type and order enums
LuanEdCosta Sep 13, 2021
ee9e8a9
Make marketplace search page responsive
LuanEdCosta Sep 13, 2021
1aa101d
Create marketplace search page skeletons
LuanEdCosta Sep 13, 2021
5a5e2d7
Add search input in marketplace pages
LuanEdCosta Sep 13, 2021
55549e6
Create usePersistentState and add tag filters in the marketplace sear…
LuanEdCosta Sep 13, 2021
975ad28
Use debouce hook in all search inputs
LuanEdCosta Sep 13, 2021
698e071
Use debouce in the marketplace initial page
LuanEdCosta Sep 14, 2021
8d891c2
Redirect and make request to API only if the filters change
LuanEdCosta Sep 14, 2021
ce1338a
Create useDebouce tests
LuanEdCosta Sep 14, 2021
80ed854
Fix useDebouce hook test suite name
LuanEdCosta Sep 14, 2021
ccc7fbb
Create tests for the usePersistentState hook
LuanEdCosta Sep 14, 2021
65337a7
Add search text in the marketplace search page results component
LuanEdCosta Sep 14, 2021
d86e331
FIx some details in the search and initial marketplace pages
LuanEdCosta Sep 14, 2021
905178e
Hide marketplace from main menu
LuanEdCosta Sep 14, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Create the marketplace search page base structure
  • Loading branch information
LuanEdCosta committed Sep 10, 2021
commit 317e8ce88171a666922016a22b43a8bf3c06935f
61 changes: 58 additions & 3 deletions src/pages/MarketplaceSearch/MarketplaceSearch.page.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';

import MarketplaceSearchHeader from './MarketplaceSearchHeader';
Expand All @@ -10,15 +10,70 @@ import './MarketplaceSearch.style.less';
const MarketplaceSearch = () => {
const history = useHistory();

const [filters, setFilters] = useState(() => {
const searchParams = new URLSearchParams(history.location.search);
const paramsObject = {};
searchParams.forEach((value, key) => {
paramsObject[key] = value === 'true'; // value is a string
});
return paramsObject;
});

const [listType, setListType] = useState('grid');
const [listOrder, setListOrder] = useState('new');

const handleGoBack = () => {
history.goBack();
};

const handleChangeFilters = (categoryKey, isChecked) => {
setFilters((currentFilters) => {
const filtersClone = { ...currentFilters };
if (isChecked) filtersClone[categoryKey] = isChecked;
else delete filtersClone[categoryKey];

history.push({
pathname: history.location.pathname,
search: `?${new URLSearchParams(filtersClone)}`,
});

return filtersClone;
});
};

const handleClearFilters = () => {
setFilters({});
history.push({
pathname: history.location.pathname,
search: '',
});
};

const handleChangeListType = () => {
setListType((currentListType) =>
currentListType === 'grid' ? 'list' : 'grid'
);
};

return (
<div className='marketplace-search'>
<MarketplaceSearchHeader handleGoBack={handleGoBack} />
<MarketplaceSearchFilters filters={{}} />
<MarketplaceSearchResults tasks={[]} />

<div className='marketplace-search-content'>
<MarketplaceSearchFilters
filters={filters}
handleClearFilters={handleClearFilters}
handleChangeFilters={handleChangeFilters}
/>

<MarketplaceSearchResults
tasks={[]}
listType={listType}
listOrder={listOrder}
handleChangeListOrder={setListOrder}
handleChangeListType={handleChangeListType}
/>
</div>
</div>
);
};
Expand Down
97 changes: 97 additions & 0 deletions src/pages/MarketplaceSearch/MarketplaceSearch.style.less
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,101 @@
}
}
}

.marketplace-search-content {
display: flex;
flex-wrap: wrap;
align-items: stretch;
flex: 1;

@media only screen and (max-width: 768px) {
flex-direction: column;
align-items: flex-start;
}
}

.marketplace-search-filters {
background: white;
width: 300px;
height: 100%;

.marketplace-search-filters-header {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
padding: 16px 24px 0 24px;

.marketplace-search-filters-header-title {
font-size: 16px;
}
}

.marketplace-search-filters-group {
padding: 24px;

&:not(:last-child) {
border-bottom: 1px solid #00000017;
}

.marketplace-search-filters-group-title {
margin: 0 0 16px 0;
}

.marketplace-search-filters-group-checkbox {
display: block;
margin: 0 0 8px 0;
}
}
}

.marketplace-search-results {
flex: 1;
display: flex;
flex-direction: column;
padding: 16px 24px;

.marketplace-search-results-header {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;

.marketplace-search-results-header-total {
> *:not(:last-child) {
margin-right: 8px;
}
}

.marketplace-search-results-header-options {
display: flex;
flex-wrap: wrap;
align-items: center;

> *:not(:last-child) {
margin-right: 8px;
}
}
}

.marketplace-search-results-tasks {
flex: 1;
display: flex;
flex-wrap: wrap;
align-items: stretch;
justify-content: flex-start;
margin: -8px;

.marketplace-search-results-task {
flex: 1 25%;
min-width: 250px;
margin: 8px;
}

.marketplace-search-results-tasks-empty {
align-self: center;
margin: 0 auto;
}
}
}
}
77 changes: 75 additions & 2 deletions src/pages/MarketplaceSearch/MarketplaceSearchFilters.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,89 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Typography, Checkbox, Button } from 'antd';

const MarketplaceSearchFilters = ({ filters }) => {
return <div>{JSON.stringify(filters)}</div>;
import { MARKETPLACE_TASK_CATEGORIES } from 'configs';

const TASK_CATEGORIES_TO_FILTER = [
MARKETPLACE_TASK_CATEGORIES.DATASETS,
MARKETPLACE_TASK_CATEGORIES.FEATURE_ENGINEERING,
MARKETPLACE_TASK_CATEGORIES.PREDICTOR,
MARKETPLACE_TASK_CATEGORIES.DESCRIPTIVE_STATISTICS,
];

const FLOW_CATEGORIES_TO_FILTER = [
MARKETPLACE_TASK_CATEGORIES.COMPUTER_VISION,
MARKETPLACE_TASK_CATEGORIES.OPTIMIZATION,
MARKETPLACE_TASK_CATEGORIES.OTHER,
];

const MarketplaceSearchFilters = ({
filters,
handleClearFilters,
handleChangeFilters,
}) => {
const mapCategoryToCheckbox = (category) => {
const isChecked = !!filters[category.key];

return (
<Checkbox
key={category.key}
checked={isChecked}
className='marketplace-search-filters-group-checkbox'
onChange={(e) => handleChangeFilters(category.key, e.target.checked)}
>
{category.name}
</Checkbox>
);
};

return (
<div className='marketplace-search-filters'>
<div className='marketplace-search-filters-header'>
<Typography.Text className='marketplace-search-filters-header-title'>
Filtrar Por:
</Typography.Text>

<Button type='link' onClick={handleClearFilters}>
Limpar Filtros
</Button>
</div>

<div className='marketplace-search-filters-group'>
<Typography.Title
className='marketplace-search-filters-group-title'
level={5}
>
TAREFAS
</Typography.Title>

{TASK_CATEGORIES_TO_FILTER.map(mapCategoryToCheckbox)}
</div>

<div className='marketplace-search-filters-group'>
<Typography.Title
className='marketplace-search-filters-group-title'
level={5}
>
FLUXOS
</Typography.Title>

{FLOW_CATEGORIES_TO_FILTER.map(mapCategoryToCheckbox)}
</div>
</div>
);
};

MarketplaceSearchFilters.propTypes = {
filters: PropTypes.object,
handleClearFilters: PropTypes.func,
handleChangeFilters: PropTypes.func,
};

MarketplaceSearchFilters.defaultProps = {
filters: {},
handleClearFilters: null,
handleChangeFilters: null,
};

export default MarketplaceSearchFilters;
102 changes: 97 additions & 5 deletions src/pages/MarketplaceSearch/MarketplaceSearchResults.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,114 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Typography, Select, Button } from 'antd';
import {
ShoppingOutlined,
UnorderedListOutlined,
BlockOutlined,
} from '@ant-design/icons';

const MarketplaceSearchResults = ({ tasks }) => {
import { MarketplaceTaskItem, Placeholder } from 'components';

const MarketplaceSearchResults = ({
tasks,
listType,
listOrder,
handleChangeListType,
handleChangeListOrder,
}) => {
return (
<div>
{tasks.map((_, index) => {
return <div key={index}></div>;
})}
<div className='marketplace-search-results'>
<div className='marketplace-search-results-header'>
<div className='marketplace-search-results-header-total'>
<Typography.Text>{tasks.length}</Typography.Text>
<Typography.Text>
{tasks.length === 1 ? 'Resultado' : 'Resultados'}
</Typography.Text>
</div>

<div className='marketplace-search-results-header-options'>
<Typography.Text>Mostrar Primeiro:</Typography.Text>

<Select
value={listOrder}
onChange={handleChangeListOrder}
placeholder='Selecione a ordem de exibição'
>
<Select.Option value='new'>Mais recentes</Select.Option>
<Select.Option value='old'>Mais antigos</Select.Option>
</Select>

<Button shape='round' onClick={handleChangeListType}>
{listType === 'list' ? (
<BlockOutlined />
) : (
<UnorderedListOutlined />
)}

<span>
{listType === 'list' ? 'Ver como grid' : 'Ver como lista'}
</span>
</Button>
</div>
</div>

<div className='marketplace-search-results-tasks'>
{tasks.map((task) => {
const handleSeeTask = () => {
history.push(`/marketplace/tarefas/${task.uuid}`);
};

return (
<MarketplaceTaskItem.Box
key={task.uuid}
onClick={handleSeeTask}
taskCategory={task.category}
className='marketplace-search-tasks-task'
header={
<MarketplaceTaskItem.Title>
{task.name}
</MarketplaceTaskItem.Title>
}
footer={
<MarketplaceTaskItem.InlineData
taskType={task.type}
taskCategory={task.category}
/>
}
>
<MarketplaceTaskItem.Description>
{task.description}
</MarketplaceTaskItem.Description>
</MarketplaceTaskItem.Box>
);
})}

{!tasks.length && (
<Placeholder
className='marketplace-search-results-tasks-empty'
message='Nenhuma tarefa ou fluxo encontrado'
iconComponent={<ShoppingOutlined />}
/>
)}
</div>
</div>
);
};

MarketplaceSearchResults.propTypes = {
tasks: PropTypes.array,
listType: PropTypes.oneOf(['list', 'grid']),
listOrder: PropTypes.oneOf(['new', 'old']),
handleChangeListType: PropTypes.func,
handleChangeListOrder: PropTypes.func,
};

MarketplaceSearchResults.defaultProps = {
tasks: [],
listType: 'grid',
listOrder: 'new',
handleChangeListType: null,
handleChangeListOrder: null,
};

export default MarketplaceSearchResults;