Skip to content

Commit

Permalink
Merge branch 'develop' into feature/consistent-type-import-webapp
Browse files Browse the repository at this point in the history
  • Loading branch information
sunilsabatp committed Jan 2, 2025
2 parents 23e3933 + 29a966d commit c4c5ad5
Show file tree
Hide file tree
Showing 34 changed files with 1,925 additions and 217 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/eslint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ on:
jobs:
ubuntu-job:
name: 'ESLint on Ubuntu'
runs-on: ubuntu-latest # Can be self-hosted runner also
runs-on: ubuntu-latest # Can be self-hosted runner also
steps:

- name: 'Checkout the repository'
uses: actions/checkout@v2

- name: Upgrade npm to latest version
run: sudo npm i -g npm@latest
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'

- name: 'Install Node Modules'
run: npm install --legacy-peer-deps
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"prepare": "node ./husky-prepare.js"
},
"validate-branch-name": {
"pattern": "^(main|develop){1}$|^(feature|hotfix|projects-redesign)/[a-z0-9-_]+$",
"pattern": "^(main|develop){1}$|^(feature|hotfix|address-mgmt)/[a-z0-9-_]+$",
"errorMsg": "Invalid branch name. \n 1.Branch names can contain lowercase characters, numbers, hyphen and underscore. \n 2.Except for 'main' and 'develop', branch names must begin with 'feature/' or 'hotfix/' "
},
"engines": {
Expand Down
10 changes: 5 additions & 5 deletions pages/sites/[slug]/[locale]/profile/edit.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { ReactElement } from 'react';
import type { AbstractIntlMessages } from 'next-intl';
import type {
GetStaticProps,
GetStaticPropsContext,
GetStaticPropsResult,
} from 'next';
import type { Tenant } from '@planet-sdk/common/build/types/tenant';
import type { AbstractIntlMessages } from 'next-intl';
import type { ReactElement } from 'react';

import Head from 'next/head';
import React from 'react';
import Head from 'next/head';
import UserLayout from '../../../../../src/features/common/Layout/UserLayout/UserLayout';
import { useTranslations } from 'next-intl';
import EditProfile from '../../../../../src/features/user/Settings/EditProfile';
Expand Down Expand Up @@ -53,7 +53,7 @@ export default EditProfilePage;
export const getStaticPaths = async () => {
const subDomainPaths = await constructPathsForTenantSlug();

const paths = subDomainPaths.map((path) => {
const paths = subDomainPaths?.map((path) => {
return {
params: {
slug: path.params.slug,
Expand Down Expand Up @@ -81,7 +81,7 @@ export const getStaticProps: GetStaticProps<PageProps> = async (

const messages = await getMessagesForPage({
locale: context.params?.locale as string,
filenames: ['common', 'me', 'country', 'editProfile'],
filenames: ['common', 'me', 'country', 'editProfile', 'profile'],
});

return {
Expand Down
11 changes: 11 additions & 0 deletions public/assets/images/icons/KebabMenuIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const KebabMenuIcon = () => {
return (
<svg viewBox="0 0 12 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="4" y="2" width="4" height="4" rx="2" fill="black" />
<rect x="4" y="8" width="4" height="4" rx="2" fill="black" />
<rect x="4" y="14" width="4" height="4" rx="2" fill="black" />
</svg>
);
};

export default KebabMenuIcon;
38 changes: 38 additions & 0 deletions public/static/locales/de/editProfile.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"email": "Email",
"address": "Adresse",
"city": "Stadt",
"state": "Bundesland",
"zipCode": "Postleitzahl",
"country": "Land",
"bio": "Profilbeschreibung",
Expand All @@ -61,11 +62,48 @@
"addressInvalid": "Adresse ist ungültig. Nur diese Sonderzeichen sind erlaubt: Leerzeichen . , # - /",
"cityRequired": "Stadt ist ein Pflichtfeld",
"cityInvalid": "Stadt ist ungültig. Nur Buchstaben und diese Sonderzeichen sind erlaubt: Leerzeichen . , ( ) -",
"stateInvalid": "Bundesland ist ungültig. Es sind nur Buchstaben und folgende Sonderzeichen erlaubt: Leerzeichen . , ( ) -",
"zipCodeRequired": "Postleitzahl ist ein Pflichtfeld",
"zipCodeInvalid": "Postleitzahl ist ungültig",
"websiteInvalid": "Bitte gib eine gültige Website-URL ein",
"countryRequired": "Land ist ein Pflichtfeld",
"companyRequired": "Firmenname ist ein Pflichtfeld"
},
"addressManagement": {
"labels": {
"actionMenu": "Aktionsmenü"
},
"addressManagementTitle": "Adresse",
"addressType": {
"primary": "Primäre Adresse",
"mailing": "Rechnungsadresse"
},
"actions": {
"edit": "Bearbeiten",
"delete": "Löschen",
"setAsPrimaryAddress": "Als primäre Adresse festlegen",
"setAsBillingAddress": "Als Rechnungsadresse festlegen",
"unsetBillingAddress": "Nicht mehr Rechnungsadresse",
"addAddress": "Neue Adresse hinzufügen"
},
"deleteAction": {
"title": "Adresse löschen",
"deleteButton": "Löschen",
"deleteAddressConfirmationMessage": "Sind Sie sicher, dass Sie diese Adresse löschen möchten? Wenn Sie sie wieder verwenden möchten, fügen Sie sie bitte als neue Adresse hinzu."
},
"updateAddressType": {
"setAddressConfirmation": "Sind Sie sicher, dass Sie diese Adresse als {addressType} festlegen möchten?",
"replaceAddressWarning": "Dies wird Ihre aktuelle {addressType} ersetzen.",
"confirmButton": "Bestätigen",
"unsetBillingAddressMessage": "Möchten Sie Ihre Rechnungsadresse ändern? Ihre Hauptadresse wird als Rechnungsadresse verwendet."
},
"maxAddressesMessage": "Sie haben die maximale Anzahl von Adressen erreicht! Entfernen Sie eine, um eine neue Adresse hinzuzufügen.",
"addressForm": {
"addAddress": "Adresse hinzufügen",
"editAddress": "Adresse bearbeiten",
"saveChanges": "Änderungen speichern",
"address2": "Adresse 2 (optional)"
}
}
}
}
38 changes: 38 additions & 0 deletions public/static/locales/en/editProfile.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"email": "Email",
"address": "Address",
"city": "City",
"state": "State",
"zipCode": "Postal/Zip Code",
"country": "Country",
"bio": "Your Description",
Expand All @@ -61,11 +62,48 @@
"addressInvalid": "Address is invalid. Only these special characters are allowed: space . , # - /",
"cityRequired": "City is required",
"cityInvalid": "City is invalid. Only letters and these special characters are allowed: space . , ( ) -",
"stateInvalid": "State is invalid. Only letters and these special characters are allowed: space . , ( ) -",
"zipCodeRequired": "Zip Code is required",
"zipCodeInvalid": "Zip Code is invalid",
"websiteInvalid": "Please enter valid Website URL",
"countryRequired": "Country is required",
"companyRequired": "Company Name is required"
},
"addressManagement": {
"labels": {
"actionMenu": "Action menu"
},
"addressManagementTitle": "Address",
"addressType": {
"primary": "Primary Address",
"mailing": "Billing Address"
},
"actions": {
"edit": "Edit",
"delete": "Delete",
"setAsPrimaryAddress": "Set as Primary Address",
"setAsBillingAddress": "Set as Billing Address",
"unsetBillingAddress": "Unset Billing Address",
"addAddress": "Add New Address"
},
"deleteAction": {
"title": "Delete Address",
"deleteButton": "Delete",
"deleteAddressConfirmationMessage": "Are you sure you want to delete this address? If you want to use it again, please add it as a new address."
},
"updateAddressType": {
"setAddressConfirmation": "Are you sure you want to set this address as your {addressType}?",
"replaceAddressWarning": "This will replace your current {addressType}.",
"confirmButton": "Confirm",
"unsetBillingAddressMessage": "Do you want to unset your billing address? Your primary address will be used as billing address."
},
"maxAddressesMessage": "You have reached the maximum number of addresses! Remove one to add a new address.",
"addressForm": {
"addAddress": "Add Address",
"editAddress": "Edit Address",
"saveChanges": "Save Changes",
"address2": "Address 2 (optional)"
}
}
}
}
11 changes: 6 additions & 5 deletions src/features/common/InputTypes/AutoCompleteCountry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import type { ReactElement, ReactNode } from 'react';
import type { CountryType, ExtendedCountryCode } from '../types/country';
import type { SetState } from '../types/common';
import type { CountryCode } from '@planet-sdk/common';

import { useState, useEffect } from 'react';
import { TextField } from '@mui/material';
import React from 'react';
import { useTranslations } from 'next-intl';
import { MuiAutoComplete, StyledAutoCompleteOption } from './MuiAutoComplete';
import { allCountries } from '../../../utils/constants/countries';
Expand Down Expand Up @@ -68,8 +68,8 @@ export default function CountrySelect({

useEffect(() => {
countries.sort((a, b) => {
const nameA = t(a.code.toLowerCase());
const nameB = t(b.code.toLowerCase());
const nameA = t(a.code.toLowerCase() as Lowercase<CountryCode>);
const nameB = t(b.code.toLowerCase() as Lowercase<CountryCode>);

//Automatic Selection option is always at first position (if present)
if (a.code === 'auto') return -1;
Expand All @@ -93,7 +93,8 @@ export default function CountrySelect({
getOptionLabel={(option) => {
const { code: countryCode, currency } = option as CountryType;
const label =
(currency ? `(${currency}) ` : '') + t(countryCode.toLowerCase());
(currency ? `(${currency}) ` : '') +
t(countryCode.toLowerCase() as Lowercase<CountryCode>);
return label;
}}
isOptionEqualToValue={(option, value) =>
Expand All @@ -103,7 +104,7 @@ export default function CountrySelect({
const { code: countryCode, currency } = option as CountryType;
const displayedOption =
(currency ? `(${currency}) ` : '') +
t(countryCode.toLowerCase()) +
t(countryCode.toLowerCase() as Lowercase<CountryCode>) +
(!(name == 'editProfile' || countryCode === 'auto')
? ` ${countryCode}`
: '');
Expand Down
22 changes: 19 additions & 3 deletions src/features/common/Layout/UserPropsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const UserPropsProvider: FC = ({ children }) => {
const [isImpersonationModeOn, setIsImpersonationModeOn] =
React.useState(false);
const [refetchUserData, setRefetchUserData] = React.useState(false);
const [redirectCount, setRedirectCount] = React.useState(0);

React.useEffect(() => {
if (localStorage.getItem('language')) {
Expand All @@ -65,13 +66,28 @@ export const UserPropsProvider: FC = ({ children }) => {

React.useEffect(() => {
async function loadToken() {
const accessToken = await getAccessTokenSilently();
setToken(accessToken);
try {
const accessToken = await getAccessTokenSilently();
setToken(accessToken);
} catch (error) {
if (process.env.NODE_ENV === 'development')
console.error('Error fetching access token:', error);

if (redirectCount < 3) {
setRedirectCount((prev) => prev + 1);
loginWithRedirect({
redirectUri: `${window.location.origin}/login`,
ui_locales: localStorage.getItem('language') || 'en',
});
} else {
console.error('Redirect limit reached, unable to authenticate user.');
}
}
}
if (!isLoading)
if (isAuthenticated) loadToken();
else setContextLoaded(true);
}, [isLoading, isAuthenticated]);
}, [isLoading, isAuthenticated, redirectCount]);

const logoutUser = (
returnUrl: string | undefined = `${window.location.origin}/`
Expand Down
6 changes: 6 additions & 0 deletions src/features/common/types/profile.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { User, UserPublicProfile } from '@planet-sdk/common';
import type { SetState } from './common';
import type { PublicUser } from './user';
import type { ADDRESS_ACTIONS } from '../../../utils/addressManagement';

export interface UserFeaturesProps {
handleShare: () => void;
Expand All @@ -25,3 +26,8 @@ export type PublicProfileV2Props = {
};

export type ProfileV2Props = PrivateProfileV2Props | PublicProfileV2Props;

// address management

export type AddressAction =
(typeof ADDRESS_ACTIONS)[keyof typeof ADDRESS_ACTIONS];
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface ProjectListControlForMobileProps {
filteredProjects: MapProject[] | undefined;
mapOptions: MapOptions;
updateMapOption: (option: keyof MapOptions, value: boolean) => void;
shouldHideProjectTabs: boolean;
}

const ProjectListControlForMobile = ({
Expand All @@ -52,14 +53,15 @@ const ProjectListControlForMobile = ({
setIsSearching,
mapOptions,
updateMapOption,
shouldHideProjectTabs,
}: ProjectListControlForMobileProps) => {
const [isFilterOpen, setIsFilterOpen] = useState(false);
const tAllProjects = useTranslations('AllProjects');
const { isImpersonationModeOn } = useUserProps();
const hasFilterApplied = selectedClassification.length > 0;
const shouldDisplayFilterResults = hasFilterApplied && selectedMode !== 'map';
const shouldDisplayProjectListTab =
!hasFilterApplied && selectedMode !== 'map';
!hasFilterApplied && selectedMode !== 'map' && !shouldHideProjectTabs;
const shouldDisplayMapFeatureExplorer = selectedMode === 'map';
const projectListControlsMobileClasses = `${
styles.projectListControlsMobile
Expand Down
38 changes: 27 additions & 11 deletions src/features/projectsV2/ProjectListControls/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { SetState } from '../../common/types/common';
import type { TreeProjectClassification } from '@planet-sdk/common';
import type { MapProject } from '../../common/types/projectv2';

import { useState } from 'react';
import { useMemo, useState } from 'react';
import { useTranslations } from 'next-intl';
import styles from './styles/ProjectListControls.module.scss';
import ActiveSearchField from './microComponents/ActiveSearchField';
Expand All @@ -22,6 +22,7 @@ export interface ProjectListControlsProps {
debouncedSearchValue: string;
setDebouncedSearchValue: SetState<string>;
filteredProjects: MapProject[] | undefined;
shouldHideProjectTabs: boolean;
}
const ProjectListControls = ({
projectCount,
Expand All @@ -33,11 +34,12 @@ const ProjectListControls = ({
debouncedSearchValue,
setDebouncedSearchValue,
filteredProjects,
shouldHideProjectTabs,
}: ProjectListControlsProps) => {
const [isFilterOpen, setIsFilterOpen] = useState(false);
const [isSearching, setIsSearching] = useState(false);
const tAllProjects = useTranslations('AllProjects');

const tCommon = useTranslations('Common');
const hasFilterApplied = selectedClassification.length > 0;

const projectListTabProps = {
Expand Down Expand Up @@ -65,21 +67,35 @@ const ProjectListControls = ({
setSelectedClassification,
};

const renderTabContent = useMemo(() => {
if (hasFilterApplied) {
return (
<div className={styles.filterResultContainer}>
{tAllProjects('filterResult', {
count: filteredProjects?.length,
})}
</div>
);
}

if (shouldHideProjectTabs) {
return (
<h2 className={styles.projectListHeaderText}>
{tCommon('stopTalkingStartPlanting')}
</h2>
);
}

return <ProjectListTabLargeScreen {...projectListTabProps} />;
}, [hasFilterApplied, shouldHideProjectTabs, filteredProjects]);

return (
<>
{isSearching ? (
<ActiveSearchField {...activeSearchFieldProps} />
) : (
<div className={styles.projectListControls}>
{hasFilterApplied ? (
<div className={styles.filterResultContainer}>
{tAllProjects('filterResult', {
count: filteredProjects?.length,
})}
</div>
) : (
<ProjectListTabLargeScreen {...projectListTabProps} />
)}
{renderTabContent}
<SearchAndFilter {...searchAndFilterProps} />
</div>
)}
Expand Down
Loading

0 comments on commit c4c5ad5

Please sign in to comment.