Skip to content

Commit

Permalink
Merge pull request #1964 from Plant-for-the-Planet-org/feature/design…
Browse files Browse the repository at this point in the history
…-projectlist-filter

project filter
  • Loading branch information
mohitb35 authored Jul 17, 2024
2 parents 15dc4d0 + 9e7f98d commit c3dcffc
Show file tree
Hide file tree
Showing 36 changed files with 1,189 additions and 221 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ on:
branches:
- develop
- feature/redesign-explore-btn
- feature/merge-from-develop
- feature/storybook-folder-structure
- feature/design-projectlist-filter
# List of jobs
jobs:
chromatic-deployment:
Expand Down
248 changes: 94 additions & 154 deletions package-lock.json

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion public/static/locales/en/allProjects.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
"currentForests": "Current Forests",
"restorationPotential": "Restoration Potential",
"deforestation": "Deforestation",
"projects": "Projects"
"projects": "Projects",
"classificationTypes": {
"large-scale-planting": "Large Scale Planting",
"agroforestry": "Agroforestry",
"natural-regeneration": "Natural Regeneration",
"managed-regeneration": "Managed Regeneration",
"urban-planting": "Urban Planting",
"other-planting": "Other Planting",
"allProjects": "All Projects"
},
"allProjects": "All <projectCountContainer>({noOfProjects})</projectCountContainer>",
"searchProject": "Search Project",
"topProjects": "Top Projects <projectCountContainer>({noOfProjects})</projectCountContainer>",
"top": "Top <projectCountContainer>({noOfProjects})</projectCountContainer>",
"list": "List",
"map": "Map"
}
}
4 changes: 2 additions & 2 deletions src/features/common/TreeCounter/TreeCounter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import theme from '../../../theme/themeProperties';
import { _tenants } from '../../../utils/constants/HomeTreeCounter';
import { useTenant } from '../Layout/TenantContext';

const { primaryDarkColorX, light } = theme;
const { primaryColorNew, light } = theme;

const CircularProgress = styled(MuiCircularProgress)({
'&.MuiCircularProgress-root': {
Expand All @@ -25,7 +25,7 @@ const CircularProgress = styled(MuiCircularProgress)({
});
const XCircularProgress = styled(MuiCircularProgress)({
'&.MuiCircularProgress-root': {
color: `${primaryDarkColorX}`,
color: `${primaryColorNew}`,
animationDuration: '550ms',
},
'& > svg > circle': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface PlantedTreesButtonProps {
}

const PlantedTreesButton = ({ plantedTrees }: PlantedTreesButtonProps) => {
const { light, primaryDarkColorX } = theme;
const { light, primaryColorNew } = theme;
const { isTreePlantedButtonActive } = useMyForest();
const t = useTranslations('Profile');
const locale = useLocale();
Expand All @@ -29,7 +29,7 @@ const PlantedTreesButton = ({ plantedTrees }: PlantedTreesButtonProps) => {
color={
isTreePlantedButtonActive
? `${light.light}`
: `${primaryDarkColorX}`
: `${primaryColorNew}`
}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const RestoredButton = ({
restoredArea,
plantedTrees,
}: RestoredButtonProps): ReactElement => {
const { primaryDarkColorX, light } = theme;
const { primaryColorNew, light } = theme;
const t = useTranslations('Profile');
const locale = useLocale();
const { isTreePlantedButtonActive } = useMyForest();
Expand All @@ -38,7 +38,7 @@ const RestoredButton = ({
color={
isTreePlantedButtonActive
? `${light.light}`
: `${primaryDarkColorX}`
: `${primaryColorNew}`
}
/>
</div>
Expand All @@ -61,7 +61,7 @@ const RestoredButton = ({
{isTreePlantedButtonActive ? (
<DownWardArrowSvg color={`${light.light}`} />
) : (
<ArrowSvg color={`${primaryDarkColorX}`} />
<ArrowSvg color={`${primaryColorNew}`} />
)}
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const TreePlantedClusterMarker = ({
geoJson,
mapRef,
}: MarkerProps): ReactElement => {
const { primaryDarkColorX } = theme;
const { primaryColorNew } = theme;
const t = useTranslations('Profile');
const [showPopUp, setShowPopUp] = useState(false);

Expand Down Expand Up @@ -51,9 +51,9 @@ export const TreePlantedClusterMarker = ({
>
<div className={MyForestMapStyle.svgContainer}>
{_isRestoredArea ? (
<RestoredSvg color={`${primaryDarkColorX}`} />
<RestoredSvg color={`${primaryColorNew}`} />
) : (
<PlantedTreesSvg color={`${primaryDarkColorX}`} />
<PlantedTreesSvg color={`${primaryColorNew}`} />
)}
</div>
<div className={MyForestMapStyle.totalTreeCount}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ const SingleMarkerImageContainer = ({
isGiftContribution,
isMergeContribution,
}: SingleMarkerImageContainerProps) => {
const { primaryDarkColorX, lightBlueColor } = theme;
const { primaryColorNew, lightBlueColor } = theme;
const _renderTreeIcon = () => {
switch (true) {
case isNormalTreeDonation ||
isRegisteredTree ||
isMergeContribution ||
isGiftContribution:
return <PlantedTreesSvg color={`${primaryDarkColorX}`} />;
return <PlantedTreesSvg color={`${primaryColorNew}`} />;
case isRestorationTreePlantation:
return <RestoredSvg color={`${primaryDarkColorX}`} />;
return <RestoredSvg color={`${primaryColorNew}`} />;
case isConservation:
return <ConservationTreeSvg color={`${lightBlueColor}`} />;
default:
Expand Down
7 changes: 5 additions & 2 deletions src/temp/ProjectInfo/ContactDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import LocationIcon from '../icons/LocationIcon';
import MailIcon from '../icons/MailIcon';
import { ViewProfileIcon } from '../icons/ViewProfileIcon';
import WebsiteLinkIcon from '../icons/WebsiteLinkIcon';
import styles from './ProjectInfo.module.scss';
import { useTranslations } from 'next-intl';
import SingleProjectInfoItem from './SingleProjectInfoItem';
import SingleContactDetail from './SingleContactDetail';
import LocationIconSolid from '../icons/LocationIconSolid';

interface Props {
websiteURL: string;
Expand Down Expand Up @@ -54,7 +54,10 @@ const ContactDetails = ({
},
{
icon: (
<LocationIcon width={9.5} color={`${'var(--primary-font-color)'}`} />
<LocationIconSolid
width={9.5}
color={`${'var(--primary-font-color)'}`}
/>
),
title: location,
link: '',
Expand Down
63 changes: 63 additions & 0 deletions src/temp/ProjectListControls/ActiveSearchField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useState, ChangeEvent, useEffect } from 'react';
import { SearchTextField } from './SearchTextField';
import CrossIcon from '../icons/CrossIcon';
import style from './ProjectListControls.module.scss';
import SearchIcon from '../icons/SearchIcon';
import { useTranslations } from 'next-intl';
import { SetState } from '../../features/common/types/common';
import { useDebouncedEffect } from '../../utils/useDebouncedEffect';

interface ActiveSearchFieldProps {
setIsSearching: SetState<boolean>;
setIsFilterOpen: SetState<boolean>;
}

const ActiveSearchField = ({
setIsSearching,
setIsFilterOpen,
}: ActiveSearchFieldProps) => {
const [searchValue, setSearchValue] = useState('');
const [debouncedSearchValue, setDebouncedSearchValue] = useState('');

useEffect(() => {
if (debouncedSearchValue) window.alert(`${debouncedSearchValue} searched!`);
}, [debouncedSearchValue]);

useDebouncedEffect(
() => {
setDebouncedSearchValue(searchValue);
},
1000,
[searchValue]
);
const t = useTranslations('AllProjects');

const resetSearchTab = () => {
setSearchValue('');
setIsSearching(false);
setIsFilterOpen(false);
};

return (
<div className={style.activeSearchFieldContainer}>
<button className={style.activeSearchIcon}>
<SearchIcon />
</button>
<SearchTextField
id="standard-search"
variant="standard"
placeholder={t('searchProject')}
value={searchValue}
onChange={(event: ChangeEvent<HTMLInputElement>) => {
setSearchValue(event.target.value);
}}
/>

<button onClick={resetSearchTab} className={style.crossIcon}>
<CrossIcon />
</button>
</div>
);
};

export default ActiveSearchField;
82 changes: 82 additions & 0 deletions src/temp/ProjectListControls/ClassificationDropDown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import style from './ProjectListControls.module.scss';
import { useTranslations } from 'next-intl';
import { Classification } from '.';
import { SetState } from '../../features/common/types/common';

interface ClassificationDropDownProps {
selectedClassification: Classification[];
availableFilters: Classification[];
setSelectedClassification: SetState<Classification[]>;
}

export const ClassificationDropDown = ({
selectedClassification,
availableFilters,
setSelectedClassification,
}: ClassificationDropDownProps) => {
const tAllProjects = useTranslations('AllProjects');

const handleFilterSelection = (filterItem: Classification): void => {
if (filterItem === 'allProjects') {
setSelectedClassification([]);
} else {
const newFilter = selectedClassification.includes(filterItem)
? selectedClassification.filter(
(classification) => classification !== filterItem
)
: [...selectedClassification, filterItem];
setSelectedClassification(newFilter);
}
};
return (
<>
{availableFilters.length > 0 ? (
<div className={style.classificationListContainer}>
<button
className={style.filterButton}
onClick={() => handleFilterSelection('allProjects')}
>
<div
className={
selectedClassification.length === 0
? style.classificationSelected
: style.classificationUnselected
}
>
{tAllProjects('classificationTypes.allProjects')}
</div>
<hr className={style.hrLine} />
</button>
<div>
{availableFilters.map((filterItem, index) => {
return (
<button
key={index}
className={style.filterButton}
onClick={() => handleFilterSelection(filterItem)}
>
<div
className={
selectedClassification?.includes(filterItem)
? style.classificationSelected
: style.classificationUnselected
}
>
{tAllProjects(`classificationTypes.${filterItem}`)}
</div>
{index !== availableFilters.length - 1 && (
<hr className={style.hrLine} />
)}
</button>
);
})}
</div>
</div>
) : (
<></>
)}
</>
);
};

export default ClassificationDropDown;
16 changes: 16 additions & 0 deletions src/temp/ProjectListControls/CustomMuiTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Tab, styled } from '@mui/material';
import themeProperties from '../../theme/themeProperties';

const { light, primaryColorNew } = themeProperties;
const CustomMuiTab = styled(Tab)(() => ({
flexDirection: 'row',
textTransform: 'none',
padding: '14px 0px',
marginLeft: '19px',
color: `${light.selectedMenuItemColorNew}`,
'&.MuiButtonBase-root.MuiTab-root.Mui-selected': {
color: `${primaryColorNew}`,
},
}));

export default CustomMuiTab;
71 changes: 71 additions & 0 deletions src/temp/ProjectListControls/ProjectListControlForMobile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { useState } from 'react';
import style from './ProjectListControls.module.scss';
import ProjectListTabForMobile from './ProjectListTabForMobile';
import { SearchAndFilter } from './ProjectSearchAndFilter';
import ViewModeTabs from './ViewModeTabs';
import ClassificationDropDown from './ClassificationDropDown';
import { ProjectListControlsProps } from '.';
import ActiveSearchField from './ActiveSearchField';
import { Classification } from '.';

const ProjectListControlForMobile = ({
availableFilters,
projectCount,
topProjectCount,
}: ProjectListControlsProps) => {
const [isFilterOpen, setIsFilterOpen] = useState(false);
const [isSearching, setIsSearching] = useState(false);
const [selectedClassification, setSelectedClassification] = useState<
Classification[]
>([]);
const [tabSelected, setTabSelected] = useState<'topProjects' | 'allProjects'>(
'topProjects'
);

return (
<>
{isSearching ? (
<div className={style.searchFieldAndViewTabsContainer}>
<ActiveSearchField
setIsFilterOpen={setIsFilterOpen}
setIsSearching={setIsSearching}
/>
<ViewModeTabs
setIsFilterOpen={setIsFilterOpen}
isSearching={isSearching}
/>
</div>
) : (
<div className={style.projectListControlsMobile}>
<ProjectListTabForMobile
projectCount={projectCount}
topProjectCount={topProjectCount}
tabSelected={tabSelected}
setTabSelected={setTabSelected}
setIsFilterOpen={setIsFilterOpen}
/>
<SearchAndFilter
selectedClassification={selectedClassification}
setIsFilterOpen={setIsFilterOpen}
isFilterOpen={isFilterOpen}
setIsSearching={setIsSearching}
isSearching={isSearching}
/>
<ViewModeTabs
setIsFilterOpen={setIsFilterOpen}
isSearching={isSearching}
/>
</div>
)}
{isFilterOpen && !isSearching && (
<ClassificationDropDown
selectedClassification={selectedClassification}
setSelectedClassification={setSelectedClassification}
availableFilters={availableFilters}
/>
)}
</>
);
};

export default ProjectListControlForMobile;
Loading

0 comments on commit c3dcffc

Please sign in to comment.