Skip to content

Commit

Permalink
wip: Filter with results and Add No Result page
Browse files Browse the repository at this point in the history
  • Loading branch information
aralovelace committed Dec 19, 2024
1 parent e2f92be commit 77571f2
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 16 deletions.
10 changes: 9 additions & 1 deletion src/components/Examples/ExamplesCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ const ExamplesCheckbox = ({
label,
name,
value,
disabled = false,
isChecked = false,
isDefaultChecked = false,
selectProductOrUseCase,
}: {
label: string;
name: string;
value: string;
disabled?: boolean;
isChecked?: boolean;
isDefaultChecked?: boolean;
selectProductOrUseCase: (e: React.ChangeEvent<HTMLInputElement>) => void;
}) => {
return (
Expand All @@ -21,7 +27,9 @@ const ExamplesCheckbox = ({
name={name}
className="ui-checkbox-input"
value={value}
defaultChecked={value === 'all'}
checked={isChecked}
defaultChecked={isDefaultChecked}
disabled={disabled}
onChange={(e) => selectProductOrUseCase(e)}
/>
<div data-ui-checkbox-styled="" className="ui-checkbox-styled">
Expand Down
61 changes: 50 additions & 11 deletions src/components/Examples/ExamplesContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,60 @@ import ExamplesFilter from './ExamplesFilter';
import { ImageProps } from '../Image';
import examples from '../../data/examples';
import { filterSearchExamples } from './filter-search-examples';
import ExamplesNoResults from './ExamplesNoResults';

const ExamplesContent = ({ exampleImages }: { exampleImages: ImageProps[] }) => {
const [selectedProducts, setSelectedProducts] = useState<string[]>(['all']);
const [selectedUseCases, setSelectedUseCases] = useState<string[]>(['all']);
const [selectedProducts, setSelectedProducts] = useState<string[]>([]);
const [selectedUseCases, setSelectedUseCases] = useState<string[]>([]);
const [checkAllProducts, setCheckAllProducts] = useState(true);
const [checkAllUseCases, setCheckAllUseCases] = useState(true);
const [filteredExamples, setFilteredExamples] = useState(examples.examples);

const selectProduct = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.checked) {
setSelectedProducts([...selectedProducts, e.target.value]);
const { value, checked } = e.target;
if (value === 'all') {
setCheckAllProducts(checked);
if (checked && selectedProducts.length > 0) {
setSelectedProducts([]);
}
} else {
setSelectedProducts(selectedProducts.filter((product) => product !== e.target.value));
if (checked) {
setSelectedProducts((prev) => [...prev, value].filter((v) => v !== 'all'));
setCheckAllProducts(false);
} else {
setSelectedProducts((prev) => prev.filter((product) => product !== value));
}
}
};

const selectUseCases = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.checked) {
setSelectedUseCases([...selectedUseCases, e.target.value]);
const { value, checked } = e.target;
if (value === 'all') {
setCheckAllUseCases(checked);
if (checked && selectedUseCases.length > 0) {
setSelectedUseCases([]);
}
} else {
setSelectedUseCases(selectedUseCases.filter((product) => product !== e.target.value));
if (checked) {
setSelectedUseCases((prev) => [...prev, value].filter((v) => v !== 'all'));
setCheckAllUseCases(false);
} else {
setSelectedUseCases((prev) => prev.filter((product) => product !== value));
}
}
};

useEffect(() => {
const filteredExamples = filterSearchExamples(examples.examples, selectedProducts, selectedUseCases);
setFilteredExamples(filteredExamples);
}, [selectedProducts, selectedUseCases]);

if (selectedProducts.length === 0) {
setCheckAllProducts(true);
}
if (selectedUseCases.length === 0) {
setCheckAllUseCases(true);
}
}, [selectedProducts, selectedUseCases, checkAllProducts, checkAllUseCases]);

return (
<>
Expand All @@ -44,10 +72,21 @@ const ExamplesContent = ({ exampleImages }: { exampleImages: ImageProps[] }) =>
</div>
<div className="w-full my-40 sm:my-64 flex flex-col sm:flex-row gap-x-40">
<div className="w-full sm:w-[20%] relative">
<ExamplesFilter selectProduct={selectProduct} selectUseCases={selectUseCases} />
<ExamplesFilter
selectProduct={selectProduct}
selectUseCases={selectUseCases}
checkAllProducts={checkAllProducts}
selectedProducts={selectedProducts}
checkAllUseCases={checkAllUseCases}
selectedUseCases={selectedUseCases}
/>
</div>
<div className="w-full sm:w-[80%] mt-40 sm:mt-0">
<ExamplesGrid exampleImages={exampleImages} examples={filteredExamples} />
{filteredExamples.length > 0 ? (
<ExamplesGrid exampleImages={exampleImages} examples={filteredExamples} />
) : (
<ExamplesNoResults />
)}
</div>
</div>
</section>
Expand Down
31 changes: 29 additions & 2 deletions src/components/Examples/ExamplesFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@ import Icon from '@ably/ui/core/Icon';
import { products } from '@ably/ui/core/ProductTile/data';
import ExamplesCheckbox from './ExamplesCheckbox';
import examples from '../../data/examples';
import './examples-checkbox.css';

const ExamplesFilter = ({
selectProduct,
selectUseCases,
checkAllProducts,
selectedProducts,
checkAllUseCases,
selectedUseCases,
}: {
selectProduct: (e: React.ChangeEvent<HTMLInputElement>) => void;
selectUseCases: (e: React.ChangeEvent<HTMLInputElement>) => void;
checkAllProducts: boolean;
selectedProducts: string[];
checkAllUseCases: boolean;
selectedUseCases: string[];
}) => {
return (
<>
Expand All @@ -25,29 +34,47 @@ const ExamplesFilter = ({
<div className="mt-20 mb-8">
<p className="ui-text-overline2 font-medium text-neutral-700">PRODUCT</p>
<div className="mt-8 flex ui-text-p4 flex-col gap-8">
<ExamplesCheckbox label="All" name="products-all" value="all" selectProductOrUseCase={selectProduct} />
<ExamplesCheckbox
label="All"
name="products-all"
value="all"
disabled={checkAllProducts}
isChecked={checkAllProducts}
selectProductOrUseCase={selectProduct}
/>
{Object.entries(products).map(([key, product]) => (
<ExamplesCheckbox
key={key}
label={product.label}
name="products-all"
value={key}
selectProductOrUseCase={selectProduct}
isDefaultChecked={!checkAllProducts}
isChecked={selectedProducts.includes(key)}
/>
))}
</div>
</div>
<div className="mt-20">
<p className="ui-text-overline2 font-medium text-neutral-700">USE CASE</p>
<div className="mt-8 flex ui-text-p4 flex-col gap-8">
<ExamplesCheckbox label="All" name="use-case-all" value="all" selectProductOrUseCase={selectUseCases} />
<ExamplesCheckbox
label="All"
name="use-case-all"
value="all"
disabled={checkAllUseCases}
isChecked={checkAllUseCases}
selectProductOrUseCase={selectUseCases}
/>
{Object.entries(examples.useCases).map(([key, useCase]) => (
<ExamplesCheckbox
key={key}
label={useCase.label}
name="use-case-all"
value={key}
selectProductOrUseCase={selectUseCases}
isDefaultChecked={!checkAllUseCases}
isChecked={selectedUseCases.includes(key)}
/>
))}
</div>
Expand Down
10 changes: 10 additions & 0 deletions src/components/Examples/ExamplesNoResults.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const ExamplesNoResults = () => {
return (
<div>
<h2>No Results</h2>
<p>Sorry, no results found.</p>
</div>
);
};

export default ExamplesNoResults;
3 changes: 3 additions & 0 deletions src/components/Examples/examples-checkbox.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.ui-checkbox-input:disabled + .ui-checkbox-styled {

}
4 changes: 2 additions & 2 deletions src/components/Examples/filter-search-examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const filterSearchExamples = (
) => {
return examples.filter(
(example) =>
(selectedProducts.includes('all') || example.products.some((product) => selectedProducts.includes(product))) &&
(selectedUseCases.includes('all') || example.useCases.some((useCase) => selectedUseCases.includes(useCase))),
(selectedProducts.length === 0 || example.products.some((product) => selectedProducts.includes(product))) &&
(selectedUseCases.length === 0 || example.useCases.some((useCase) => selectedUseCases.includes(useCase))),
);
};

0 comments on commit 77571f2

Please sign in to comment.