-
Notifications
You must be signed in to change notification settings - Fork 15
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
Update v2 projects routes, and archive old project pages at /projects-archive #2296
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
WalkthroughThe pull request introduces significant modifications across several files, primarily focusing on the routing logic and component visibility based on the pathname. Key changes include the introduction of a new URL structure that incorporates "projects-archive" for project-related pages, updates to type definitions for better type safety, and the removal of redundant state management. Additionally, several components have been streamlined to enhance modularity and maintainability, while some files have been deleted as their functionalities have been integrated elsewhere. Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Outside diff range and nitpick comments (23)
src/features/projects/components/maps/MapHolder.tsx (1)
18-19
: Consider using exact path matching instead of substring inclusion.While the simplified condition aligns with the PR objectives, using
includes()
for path matching could potentially match unintended future routes that contain 'projects-archive' as a substring. Consider using a more precise matching approach.- router.pathname.includes('projects-archive') && + router.pathname.startsWith('/projects-archive') &&src/features/projects/components/maps/ProjectTabs.tsx (1)
20-21
: Consider using boolean type for showProjectDetails.The string comparison
showProjectDetails === 'false'
suggests thatshowProjectDetails
might be a string when it should ideally be a boolean. Consider updating the type and comparison.- showProjectDetails === 'false' + showProjectDetails === falseAlso update the type in the ParamsContext:
interface ParamsContextType { // ... other properties - showProjectDetails: string; + showProjectDetails: boolean; // ... other properties }src/features/projects/components/maps/SitesDropdown.tsx (1)
37-39
: Consider adding error handling for invalid navigation.While the URL structure update is correct, consider adding error handling for cases where project.slug or site ID might be invalid.
router.push( - `/projects-archive/${project.slug}?site=${ - geoJson.features[event.target.value as unknown as number].properties.id - }` + `/projects-archive/${project.slug}?site=${ + geoJson.features[event.target.value as unknown as number]?.properties?.id ?? '' + }`, + undefined, + { shallow: true } );src/features/projectsV2/ProjectsMap/ProjectMarkers/index.tsx (1)
Line range hint
40-49
: Consider extracting URL construction logic.The URL construction with query parameters could be simplified by extracting it into a utility function, making it reusable and easier to maintain.
Consider creating a utility function:
const buildProjectUrl = ( locale: string, projectSlug: string, embed?: string, callbackUrl?: string ): string => { const baseUrl = `/${locale}/${projectSlug}`; if (embed !== 'true') return baseUrl; const params = new URLSearchParams(); params.append('embed', 'true'); if (callbackUrl) params.append('callback', callbackUrl); return `${baseUrl}?${params.toString()}`; };Then use it in the component:
- `/${locale}/${projectSlug}${ - embed === 'true' - ? `${ - callbackUrl != undefined - ? `?embed=true&callback=${callbackUrl}` - : '?embed=true' - }` - : '' - }` + buildProjectUrl(locale, projectSlug, embed, callbackUrl)src/features/projects/components/maps/Markers.tsx (1)
Line range hint
52-61
: LGTM with a security suggestion.The URL structure change to use
/projects-archive/
aligns well with the PR objectives. However, consider encoding the callback URL to prevent potential XSS attacks.Apply this diff to improve security:
`/${locale}/projects-archive/${projectSlug}${ embed === 'true' ? `${ callbackUrl != undefined - ? `?embed=true&callback=${callbackUrl}` + ? `?embed=true&callback=${encodeURIComponent(callbackUrl)}` : '?embed=true' }` : '' }`src/features/projects/components/maps/Project.tsx (1)
103-104
: Consider making the condition check more explicit.The current condition could be more explicit about handling null/undefined cases.
- if (selectedPl) + if (selectedPl !== null && selectedPl !== undefined)src/features/projectsV2/ProjectSnippet/microComponents/ImageSection.tsx (1)
49-49
: LGTM! Consider enhancing navigation context.The removal of
/prd
prefix aligns with the PR objectives of moving v2 projects to root routes.Consider enhancing the default navigation by determining if the user is viewing an archived project:
- const defaultRoute = `/${locale}`; + const defaultRoute = page === 'archived-project' + ? `/${locale}/projects-archive` + : `/${locale}`;This would provide a more intuitive navigation experience by returning users to the appropriate project listing page.
src/features/common/Layout/Footer/SelectLanguageAndCountry.tsx (2)
175-175
: Fix typo in TODO comment.The comment contains a typo: "TODOO" should be "TODO".
- // TODOO - loader while changing the locale + // TODO - loader while changing the locale
Line range hint
176-186
: Consider refactoring URL manipulation logic.The current URL manipulation logic using string splitting and joining could be simplified using the URL API for better maintainability and robustness.
Here's a suggested refactor:
- if (pathname === '/sites/[slug]/[locale]' || pathname === `/${locale}`) { - router.replace(encodeURI(`/${modalLanguage}`)); - } else { - const splitPathnames = asPath.split('/'); - if (splitPathnames.length > 2) { - const newPathname = splitPathnames.slice(2).join('/'); - router.replace(encodeURI(`/${modalLanguage}/${newPathname}`)); - } else { - router.replace(encodeURI(`/${modalLanguage}`)); - } - } + const url = new URL(asPath, window.location.origin); + const pathSegments = url.pathname.split('/').filter(Boolean); + + if (pathname === '/sites/[slug]/[locale]' || pathname === `/${locale}`) { + router.replace(`/${modalLanguage}`); + } else { + const newPathname = pathSegments.length > 1 + ? `/${modalLanguage}/${pathSegments.slice(1).join('/')}` + : `/${modalLanguage}`; + router.replace(newPathname); + }This refactor:
- Uses the URL API for more robust path manipulation
- Simplifies the logic by reducing nesting
- Removes redundant
encodeURI
calls as Next.js router handles encodingsrc/features/projects/screens/SingleProjectDetails.tsx (1)
Line range hint
103-110
: Consider extracting the base path as a constant.The changes correctly implement the new routing structure. However, to improve maintainability, consider extracting the base path as a constant:
+ const PROJECTS_ARCHIVE_BASE_PATH = '/projects-archive'; router.replace({ - pathname: `/${locale}/projects-archive`, + pathname: `/${locale}${PROJECTS_ARCHIVE_BASE_PATH}`, query: { ...(isEmbed ? { embed: 'true' } : {}), ...(isEmbed && callbackUrl !== undefined ? { callback: callbackUrl } : {}), }, });This would:
- Make it easier to update the path in the future
- Ensure consistency across both router.push and router.replace calls
- Reduce the risk of typos
src/features/projects/components/ProjectSnippet.tsx (1)
Line range hint
123-135
: LGTM! Consider using URL utility for better maintainability.The URL construction for the projects archive aligns with the PR objectives. However, consider using a URL utility function to handle the path construction, making it more maintainable and reusable across components.
+ // Add to a shared utility file (e.g., src/utils/urlHelpers.ts) + export const getProjectArchiveUrl = ( + locale: string, + slug: string, + embed?: string, + callback?: string + ) => { + const base = `/${locale}/projects-archive/${slug}`; + if (embed !== 'true') return base; + return `${base}${callback ? `?embed=true&callback=${callback}` : '?embed=true'}`; + }; // In ProjectSnippet.tsx - router.push( - `/${locale}/projects-archive/${project.slug}${ - embed === 'true' - ? `${ - callbackUrl != undefined - ? `?embed=true&callback=${callbackUrl}` - : '?embed=true' - }` - : '' - }` - ); + router.push(getProjectArchiveUrl(locale, project.slug, embed, callbackUrl));pages/_app.tsx (3)
Line range hint
171-175
: Consider using route constants for path checking.While the logic is correct, using string literals for path checking can be fragile if route patterns change. Consider defining route constants to make the code more maintainable.
+// Add to a constants file +export const ROUTES = { + PROJECTS_ARCHIVE: 'projects-archive' +} as const; - if (router.pathname.includes('projects-archive')) { + if (router.pathname.includes(ROUTES.PROJECTS_ARCHIVE)) {
Line range hint
210-224
: Several improvements needed for video visibility logic.The current implementation has several issues that should be addressed:
- The pathname check is inconsistent with the map visibility logic (
endsWith
vsincludes
).- Direct localStorage access without error handling could throw in some browsers.
- Missing cleanup in useEffect could cause memory leaks.
- Direct localStorage mutation without proper state management.
Here's a suggested improvement:
+const VIDEO_STORAGE_KEY = 'showVideo'; +const getStoredVideoPreference = () => { + try { + return localStorage.getItem(VIDEO_STORAGE_KEY) === 'true'; + } catch (e) { + console.error('Failed to access localStorage:', e); + return true; // default value + } +}; +const setStoredVideoPreference = (value: boolean) => { + try { + localStorage.setItem(VIDEO_STORAGE_KEY, String(value)); + } catch (e) { + console.error('Failed to store video preference:', e); + } +}; React.useEffect(() => { - if (router.pathname.endsWith('projects-archive')) { + if (router.pathname.includes(ROUTES.PROJECTS_ARCHIVE)) { if (typeof window !== 'undefined') { - if (localStorage.getItem('showVideo')) { - if (localStorage.getItem('showVideo') === 'true') { - setLocalShowVideo(true); - } else { - setLocalShowVideo(false); - } - } else { - localStorage.setItem('showVideo', 'true'); - setLocalShowVideo(true); - } + const preference = getStoredVideoPreference(); + if (!preference) setStoredVideoPreference(true); + setLocalShowVideo(preference); } } else { setLocalShowVideo(false); } + return () => { + // Cleanup if needed + }; - }, []); + }, [router.pathname]);
Line range hint
11-13
: Plan cleanup of old projects code.There are several TODO comments indicating that old projects code needs to be removed. Consider:
- Creating a tracking issue for the cleanup
- Documenting which components and styles are part of the old implementation
- Planning a timeline for the removal to avoid technical debt accumulation
Would you like me to help create a GitHub issue to track this cleanup task?
Also applies to: 15-16
src/features/projects/components/maps/Explore.tsx (2)
Line range hint
172-183
: Security: Validate callback URL to prevent open redirect vulnerability.The
callbackUrl
parameter is used directly in URL construction without validation, which could lead to open redirect vulnerabilities.Consider adding URL validation:
router.push( - `${locale}/projects-archive${ - embed === 'true' - ? `${ - callbackUrl != undefined - ? `?embed=true&callback=${callbackUrl}` - : '?embed=true' - }` - : '' - }`, + `${locale}/projects-archive${ + embed === 'true' + ? `?embed=true${ + callbackUrl != undefined && isValidUrl(callbackUrl) + ? `&callback=${encodeURIComponent(callbackUrl)}` + : '' + }` + : '' + }`, undefined, { shallow: true, } ); // Add this helper function + function isValidUrl(url: string): boolean { + try { + const parsedUrl = new URL(url); + // Add additional validation rules as needed + return ['http:', 'https:'].includes(parsedUrl.protocol); + } catch (e) { + return false; + } + }
Line range hint
172-183
: Refactor: Simplify URL construction logic.The URL construction using template literals is complex and could be simplified for better maintainability.
Consider extracting the URL construction logic:
+ const buildProjectsArchiveUrl = ( + locale: string, + embed: string, + callbackUrl?: string + ): string => { + const params = new URLSearchParams(); + if (embed === 'true') { + params.set('embed', 'true'); + if (callbackUrl && isValidUrl(callbackUrl)) { + params.set('callback', callbackUrl); + } + } + const queryString = params.toString(); + return `${locale}/projects-archive${queryString ? `?${queryString}` : ''}`; + }; router.push( - `${locale}/projects-archive${ - embed === 'true' - ? `${ - callbackUrl != undefined - ? `?embed=true&callback=${callbackUrl}` - : '?embed=true' - }` - : '' - }`, + buildProjectsArchiveUrl(locale, embed, callbackUrl), undefined, { shallow: true, } );src/features/projectsV2/ProjectsContext.tsx (2)
Line range hint
371-379
: Consider handling invalid site index more explicitly.In the site selection logic, when handling a direct link with an invalid site ID, the code silently falls back to index 0. Consider making this fallback behavior more explicit and possibly logging a warning for debugging purposes.
if (index !== undefined) { + if (index === -1) { + console.warn(`Invalid site ID: ${requestedSite}, falling back to first site`); + } updateSiteAndUrl(locale, singleProject.slug, index !== -1 ? index : 0); return; }
Line range hint
252-266
: Enhance type safety for query parameters.Consider creating a type for the expected query parameters to improve type safety and maintainability.
type ProjectQueryParams = { locale?: string; slug?: string; p?: string; ploc?: string; site?: string; [key: string]: string | undefined; }; const updateProjectDetailsPath = ( locale: string, projectSlug: string, queryParams: ProjectQueryParams = {} ) => { // ... rest of the function };pages/sites/[slug]/[locale]/index.tsx (2)
1-5
: Import types from 'next' instead of 'next/types'It's standard practice to import Next.js types from
'next'
rather than'next/types'
. Importing from'next'
ensures compatibility and follows conventional usage.Apply this diff to adjust the import:
-import type { - GetStaticProps, - GetStaticPropsContext, - GetStaticPropsResult, -} from 'next/types'; +import type { + GetStaticProps, + GetStaticPropsContext, + GetStaticPropsResult, +} from 'next';
43-48
: Consider removing unnecessaryas const
assertionThe
as const
assertion onlayoutProps
may be unnecessary unless you need to enforce literal types for its properties. Removing it can simplify the code without affecting functionality.Apply this diff to remove the
as const
:const layoutProps = { currencyCode: pageComponentProps.currencyCode, setCurrencyCode: pageComponentProps.setCurrencyCode, page: 'project-list', isMobile: pageComponentProps.isMobile, - } as const; + };pages/sites/[slug]/[locale]/projects-archive/[p].tsx (3)
206-220
: Simplify conditional rendering for better readabilityThe return statement contains unnecessary fragments and empty elements, making the code less readable.
Simplify the conditional rendering as follows:
return pageProps.tenantConfig ? ( <> {project && <ProjectDetailsMeta project={project} />} {project && <SingleProjectDetails />} <Credits setCurrencyCode={setCurrencyCode} /> </> ) : null;
223-240
: Generate paths for all supported locales ingetStaticPaths
In
getStaticPaths
, only'en'
is used as the locale (line 231). If your application supports multiple locales, you should generate paths for each to ensure proper localization.Modify
getStaticPaths
to include all supported locales:- locale: 'en', + locale,You'll need to loop over your supported locales when constructing the paths.
248-264
: Validate and fallback thelocale
ingetStaticProps
In
getStaticProps
, thelocale
is directly taken fromcontext.params?.locale
without validation, which could lead to issues if an unsupported locale is provided.Ensure that the
locale
is valid and provide a fallback if necessary:const locale = validateLocale(context.params?.locale) ? context.params?.locale : 'en';Implement a
validateLocale
function or use existing utilities to check for supported locales.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (21)
pages/_app.tsx
(2 hunks)pages/sites/[slug]/[locale]/[p].tsx
(3 hunks)pages/sites/[slug]/[locale]/index.tsx
(2 hunks)pages/sites/[slug]/[locale]/prd/[p].tsx
(0 hunks)pages/sites/[slug]/[locale]/prd/index.tsx
(0 hunks)pages/sites/[slug]/[locale]/projects-archive/[p].tsx
(1 hunks)pages/sites/[slug]/[locale]/projects-archive/index.tsx
(1 hunks)src/features/common/LandingVideo/PlayButton.tsx
(1 hunks)src/features/common/Layout/Footer/SelectLanguageAndCountry.tsx
(1 hunks)src/features/projects/components/ProjectSnippet.tsx
(1 hunks)src/features/projects/components/maps/Explore.tsx
(3 hunks)src/features/projects/components/maps/MapHolder.tsx
(1 hunks)src/features/projects/components/maps/Markers.tsx
(1 hunks)src/features/projects/components/maps/Project.tsx
(1 hunks)src/features/projects/components/maps/ProjectTabs.tsx
(1 hunks)src/features/projects/components/maps/SitesDropdown.tsx
(3 hunks)src/features/projects/screens/SingleProjectDetails.tsx
(2 hunks)src/features/projectsV2/ProjectSnippet/microComponents/ImageSection.tsx
(1 hunks)src/features/projectsV2/ProjectsContext.tsx
(1 hunks)src/features/projectsV2/ProjectsMap/ProjectMarkers/index.tsx
(1 hunks)src/utils/projectV2.ts
(1 hunks)
💤 Files with no reviewable changes (2)
- pages/sites/[slug]/[locale]/prd/[p].tsx
- pages/sites/[slug]/[locale]/prd/index.tsx
🔇 Additional comments (23)
src/features/common/LandingVideo/PlayButton.tsx (2)
24-25
: LGTM! Path updates align with project archival strategy.
The pathname checks have been correctly updated to use the new /projects-archive/[p]
routes, which aligns with the PR objective of archiving old project pages.
24-25
: Verify consistent pathname updates across the codebase.
Let's ensure all related components have been updated to use the new /projects-archive
path pattern consistently.
✅ Verification successful
Path pattern /projects-archive/[p]
is consistently used across the codebase
The verification shows that all components using the [p]
path parameter are consistently using the /projects-archive/[p]
pattern:
src/features/common/LandingVideo/PlayButton.tsx
src/features/projects/components/maps/SitesDropdown.tsx
src/features/projects/components/maps/ProjectTabs.tsx
Each component properly handles both the direct path /projects-archive/[p]
and where applicable, the nested path /sites/[slug]/[locale]/projects-archive/[p]
.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Search for any remaining old project path patterns that might need updating
# Test 1: Search for old path patterns that might need updating
echo "Checking for potential missed path updates..."
rg -l "'/\[p\]'" --type ts --type tsx
# Test 2: Verify new path pattern usage is consistent
echo "Verifying new path pattern usage..."
rg -l "'/projects-archive/\[p\]'" --type ts --type tsx
# Test 3: Check for any mixed usage of old and new patterns
echo "Checking for components that might have mixed path patterns..."
rg "pathname.*\[p\]" --type ts --type tsx
Length of output: 553
Script:
#!/bin/bash
# Let's try with correct ripgrep file type options and proper escaping
# Test 1: Search for any path patterns with [p]
echo "Checking path patterns with [p]..."
rg --type-add 'tsx:*.tsx' --type-add 'ts:*.ts' -l "pathname.*\[p\]"
# Test 2: Look specifically for the projects-archive pattern
echo "Checking projects-archive patterns..."
rg --type-add 'tsx:*.tsx' --type-add 'ts:*.ts' -l "projects-archive/\[p\]"
# Test 3: Get more context around the pathname usages
echo "Checking pathname context..."
rg --type-add 'tsx:*.tsx' --type-add 'ts:*.ts' -A 2 -B 2 "pathname.*\[p\]"
Length of output: 2773
src/features/projects/components/maps/ProjectTabs.tsx (1)
20-21
: LGTM! Route change aligns with PR objectives.
The updated condition correctly handles the new /projects-archive/[p]
route structure, which is consistent with the PR's goal of archiving old project routes.
src/features/projects/components/maps/SitesDropdown.tsx (1)
47-49
: LGTM: Consistent pathname checks for archived projects.
The pathname checks are correctly updated to reflect the new routing structure with "/projects-archive/", maintaining consistent styling logic across the component.
Also applies to: 57-59
src/features/projectsV2/ProjectsMap/ProjectMarkers/index.tsx (1)
Line range hint 40-49
: Verify handling of archived projects.
The URL structure change aligns with the PR objectives by removing the /prd
prefix. However, we should verify if archived projects need to be handled differently.
Let's check if there are any conditions that determine whether a project should use the archive route:
src/features/projects/components/maps/Project.tsx (1)
103-104
: LGTM! Routing change aligns with PR objectives.
The URL path modification correctly implements the new routing structure by redirecting to /projects-archive/${project.slug}
, maintaining the plant location query parameter.
src/features/common/Layout/Footer/SelectLanguageAndCountry.tsx (1)
176-176
: LGTM: Additional pathname check for root-level locale paths.
The added condition correctly handles locale switching for root-level paths (e.g., /en
, /de
), which aligns with the PR's objective of moving v2 pages to root routes.
src/utils/projectV2.ts (2)
219-221
: LGTM! URL structure simplified as intended.
The removal of the /prd
prefix aligns with the PR objective to relocate v2 project pages to root routes.
219-221
: Verify handling of existing /prd
URLs.
While the URL structure change is correct, we should ensure proper handling of existing bookmarked URLs.
Let's check for any remaining /prd
references and verify redirect handling:
src/features/projects/screens/SingleProjectDetails.tsx (1)
Line range hint 88-97
: LGTM: URL path update aligns with archival requirements.
The modification correctly implements the new /projects-archive
route structure while preserving the existing query parameter handling for embedded views and callbacks.
src/features/projects/components/maps/Explore.tsx (2)
5-5
: LGTM: Import addition aligns with localization needs.
The addition of useLocale
import is appropriate for handling localized routes in the new URL structure.
Line range hint 172-183
: Verify locale handling in URL construction.
The code assumes the locale value is always valid and available. We should verify how invalid or missing locales are handled.
✅ Verification successful
Let me gather more information about the locale handling by examining the identified configuration files.
Based on the gathered information, I can now provide the final response:
Locale handling is properly implemented and validated at the middleware level
The locale handling in the URL construction is safe because:
- The middleware (
middleware.ts
) validates locales against supported languages and provides fallback to default locale - Invalid or missing locales are automatically handled through:
- Validation against
i18nConfig.locales
which defines supported locales (en
,de
,cs
,es
,fr
,it
,pt-BR
) - Tenant-specific locale filtering via
commonSupportedLocales
- Fallback to
defaultLocale: 'en'
when errors occur
- Validation against
- The
useLocale()
hook used in the Explore component is provided by the framework and guaranteed to return a valid locale
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for locale validation in the codebase
# Look for locale validation patterns
echo "Searching for locale validation patterns..."
rg -A 3 "useLocale|getLocale|validateLocale" --type ts --type tsx
# Look for locale-related error handling
echo "Searching for locale-related error handling..."
rg -A 3 "defaultLocale|fallbackLocale" --type ts --type tsx
# Look for middleware or configuration files that might handle locale
echo "Searching for locale configuration..."
fd -e ts -e js "middleware|i18n|locale"
Length of output: 549
Script:
#!/bin/bash
# Check the content of locale-related configuration files
echo "=== Content of i18n-config.ts ==="
cat i18n-config.ts
echo -e "\n=== Content of i18n.ts ==="
cat i18n.ts
echo -e "\n=== Content of middleware.ts ==="
cat middleware.ts
# Search for locale usage in the specific component
echo -e "\n=== Checking locale usage in Explore component ==="
rg -A 5 "locale" src/features/projects/components/maps/Explore.tsx || true
# Look for any locale-related hooks or context usage
echo -e "\n=== Checking for locale-related hooks or context ==="
ast-grep --pattern 'const $_ = use$_()' src/features/projects/components/maps/Explore.tsx || true
Length of output: 10149
src/features/projectsV2/ProjectsContext.tsx (1)
253-253
: LGTM! Verify the impact of URL structure change.
The removal of '/prd' from the pathname aligns with the PR objectives. The implementation correctly maintains the locale and project slug while properly handling query parameters.
Let's verify that no other components still expect the '/prd' prefix:
✅ Verification successful
URL path structure change is safe to proceed
Based on the comprehensive search results, the removal of '/prd' from the pathname is safe as there are no remaining references to this prefix in the codebase. All project-related URL constructions follow the new pattern of /${locale}/${projectSlug}
, consistent with the change in ProjectsContext.tsx
. The URL handling across components (ProjectSnippet, ProjectMarkers, ProjectDetails) all align with this structure.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any remaining references to '/prd' in the codebase
rg "/prd" --type tsx --type ts
Length of output: 58
Script:
#!/bin/bash
# Search for any remaining references to '/prd' in the codebase using ripgrep
# Note: Using --type-add to properly recognize TypeScript/TSX files
rg "/prd" --type-add 'typescript:*.{ts,tsx}' --type typescript
Length of output: 62
Script:
#!/bin/bash
# Let's try a more comprehensive search for URL patterns in TypeScript files
# Search for route definitions and URL manipulations
rg -A 2 -B 2 "pathname\s*=|route\s*=|path\s*=" --type-add 'typescript:*.{ts,tsx}' --type typescript
# Also search for any project-related route handling
rg -A 2 -B 2 "projectSlug|projectId.*route" --type-add 'typescript:*.{ts,tsx}' --type typescript
Length of output: 17335
pages/sites/[slug]/[locale]/[p].tsx (9)
1-6
: Appropriate use of TypeScript imports for Next.js and React types
The imports for GetStaticProps
, GetStaticPropsContext
, GetStaticPropsResult
, and ReactElement
enhance type safety and clarity in your Next.js application.
7-11
: Consistent import of custom page component types
Importing NextPageWithLayout
, PageComponentProps
, and PageProps
from your _app
ensures consistent typing across your application, promoting maintainability.
19-25
: Correctly importing necessary hooks and components
The imports for useRouter
, useTenant
, useEffect
, v4
, ProjectsLayout
, MobileProjectsLayout
, and ProjectDetails
are appropriately included, setting up the component for proper functionality.
27-31
: Simplified component props destructuring for better readability
Destructuring pageProps
, currencyCode
, and isMobile
directly in the component parameters improves readability and reduces the need for an explicit Props
interface.
35-40
: Effective use of useEffect
to set tenant configuration
Using useEffect
with router.isReady
to set the tenant configuration ensures that the configuration is applied once the router is ready, preventing potential issues with uninitialized routes.
41-42
: Rendering ProjectDetails
with necessary props
Passing currencyCode
and isMobile
to the ProjectDetails
component aligns with the expected prop interface, ensuring consistent behavior across different devices.
44-59
: Conditional layout rendering based on device type
The getLayout
function effectively switches between MobileProjectsLayout
and ProjectsLayout
based on the isMobile
prop, promoting a responsive design that adapts to different screen sizes.
77-77
: Using fallback: 'blocking'
in getStaticPaths
Setting fallback
to 'blocking'
allows for dynamic generation of pages not generated at build time, which is appropriate for handling a large number of paths.
90-99
: Expanded localization support with additional message files
Including more filenames in getMessagesForPage
, such as 'allProjects'
, 'projectDetails'
, 'donate'
, etc., enhances the application's internationalization capabilities, supporting a wider range of localized content.
pages/sites/[slug]/[locale]/projects-archive/index.tsx (1)
89-95
:
Include router.query.p
in the useEffect
dependencies
The useEffect
hook relies on router.query.p
, but the dependency array only includes [router]
. To ensure the effect runs when router.query.p
changes, include it in the dependency array.
Apply this diff to update the dependency array:
- }, [router]);
+ }, [router.query.p]);
Likely invalid or redundant comment.
useEffect(() => { | ||
if (router.isReady) { | ||
setTenantConfig(pageProps.tenantConfig); | ||
} | ||
}, [router.isReady]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include all dependencies in the useEffect
dependency array
The useEffect
hook depends on router.isReady
, setTenantConfig
, and pageProps.tenantConfig
. To comply with React's Hooks rules and prevent potential bugs, include all these dependencies in the dependency array.
Apply this diff to update the dependency array:
useEffect(() => {
if (router.isReady) {
setTenantConfig(pageProps.tenantConfig);
}
-}, [router.isReady]);
+}, [router.isReady, setTenantConfig, pageProps.tenantConfig]);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
useEffect(() => { | |
if (router.isReady) { | |
setTenantConfig(pageProps.tenantConfig); | |
} | |
}, [router.isReady]); | |
useEffect(() => { | |
if (router.isReady) { | |
setTenantConfig(pageProps.tenantConfig); | |
} | |
}, [router.isReady, setTenantConfig, pageProps.tenantConfig]); |
React.useEffect(() => { | ||
if (router.isReady) { | ||
setTenantConfig(pageProps.tenantConfig); | ||
} | ||
}, [router.isReady]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add missing dependency pageProps.tenantConfig
to the useEffect
hook
The useEffect
hook depends on pageProps.tenantConfig
, but the dependency array only includes [router.isReady]
. To ensure that setTenantConfig
is called whenever pageProps.tenantConfig
changes, include it in the dependency array.
Apply this diff to include the missing dependency:
- }, [router.isReady]);
+ }, [router.isReady, pageProps.tenantConfig]);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
React.useEffect(() => { | |
if (router.isReady) { | |
setTenantConfig(pageProps.tenantConfig); | |
} | |
}, [router.isReady]); | |
React.useEffect(() => { | |
if (router.isReady) { | |
setTenantConfig(pageProps.tenantConfig); | |
} | |
}, [router.isReady, pageProps.tenantConfig]); |
React.useEffect(() => { | ||
async function loadProjects() { | ||
if ( | ||
!internalCurrencyCode || | ||
currencyCode !== internalCurrencyCode || | ||
internalLanguage !== locale | ||
) { | ||
const currency = getStoredCurrency(); | ||
setInternalCurrencyCode(currency); | ||
setCurrencyCode(currency); | ||
setInternalLanguage(locale); | ||
try { | ||
const projects = await getRequest<MapProject[]>( | ||
pageProps.tenantConfig.id, | ||
`/app/projects`, | ||
{ | ||
_scope: 'map', | ||
currency: currency, | ||
tenant: pageProps.tenantConfig.id, | ||
'filter[purpose]': 'trees,conservation', | ||
locale: locale, | ||
} | ||
); | ||
setProjects(projects); | ||
setProject(null); | ||
setShowSingleProject(false); | ||
setZoomLevel(1); | ||
} catch (err) { | ||
setErrors(handleError(err as APIError)); | ||
redirect('/'); | ||
} | ||
} | ||
} | ||
loadProjects(); | ||
}, [currencyCode, locale]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add missing dependencies to the useEffect
hook for loading projects
The useEffect
hook depends on internalCurrencyCode
, currencyCode
, internalLanguage
, and locale
, but the dependency array only includes [currencyCode, locale]
. To ensure that the effect responds to changes in all relevant variables, include them in the dependency array.
Apply this diff to update the dependency array:
- }, [currencyCode, locale]);
+ }, [internalCurrencyCode, internalLanguage, currencyCode, locale]);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
React.useEffect(() => { | |
async function loadProjects() { | |
if ( | |
!internalCurrencyCode || | |
currencyCode !== internalCurrencyCode || | |
internalLanguage !== locale | |
) { | |
const currency = getStoredCurrency(); | |
setInternalCurrencyCode(currency); | |
setCurrencyCode(currency); | |
setInternalLanguage(locale); | |
try { | |
const projects = await getRequest<MapProject[]>( | |
pageProps.tenantConfig.id, | |
`/app/projects`, | |
{ | |
_scope: 'map', | |
currency: currency, | |
tenant: pageProps.tenantConfig.id, | |
'filter[purpose]': 'trees,conservation', | |
locale: locale, | |
} | |
); | |
setProjects(projects); | |
setProject(null); | |
setShowSingleProject(false); | |
setZoomLevel(1); | |
} catch (err) { | |
setErrors(handleError(err as APIError)); | |
redirect('/'); | |
} | |
} | |
} | |
loadProjects(); | |
}, [currencyCode, locale]); | |
React.useEffect(() => { | |
async function loadProjects() { | |
if ( | |
!internalCurrencyCode || | |
currencyCode !== internalCurrencyCode || | |
internalLanguage !== locale | |
) { | |
const currency = getStoredCurrency(); | |
setInternalCurrencyCode(currency); | |
setCurrencyCode(currency); | |
setInternalLanguage(locale); | |
try { | |
const projects = await getRequest<MapProject[]>( | |
pageProps.tenantConfig.id, | |
`/app/projects`, | |
{ | |
_scope: 'map', | |
currency: currency, | |
tenant: pageProps.tenantConfig.id, | |
'filter[purpose]': 'trees,conservation', | |
locale: locale, | |
} | |
); | |
setProjects(projects); | |
setProject(null); | |
setShowSingleProject(false); | |
setZoomLevel(1); | |
} catch (err) { | |
setErrors(handleError(err as APIError)); | |
redirect('/'); | |
} | |
} | |
} | |
loadProjects(); | |
}, [internalCurrencyCode, internalLanguage, currencyCode, locale]); |
} | ||
} catch (err) { | ||
setErrors(handleError(err as APIError | ClientError)); | ||
redirect('/'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Include locale
in the error redirect
When redirecting after an error in line 120, the path '/'
doesn't include the locale
, which may result in the user landing on a page with the wrong language.
Modify the redirect
call to include locale
:
- redirect('/');
+ redirect(`/${locale}/`);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
redirect('/'); | |
redirect(`/${locale}/`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add this as an issue, as it is many places and is not related to this PR specifically
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mohitb35, I've created the issue to track this problem across the codebase: #2297.
I've noted this for future reviews.
🔗 Analysis chain
@mohitb35, understood. I'll create a new issue to track this problem across the codebase.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Create a new GitHub issue to address the locale parameter in redirects
gh issue create \
--title "Redirects should include locale parameter" \
--body "In multiple places across the codebase, redirects after errors do not include the \`locale\` in the path. This may result in users landing on pages with the wrong language.
**PR:** https://github.com/Plant-for-the-Planet-org/planet-webapp/pull/2296
**Comment:** https://github.com/Plant-for-the-Planet-org/planet-webapp/pull/2296#discussion_r1832677705
Reported by @mohitb35." \
--assignee mohitb35
Length of output: 545
✏️ Learnings added
Learnt from: mohitb35
PR: Plant-for-the-Planet-org/planet-webapp#2296
File: pages/sites/[slug]/[locale]/projects-archive/[p].tsx:120-120
Timestamp: 2024-11-07T13:33:42.538Z
Learning: When redirecting after an error, ensure that the redirect includes the `locale` parameter in the path to prevent users from landing on a page with the wrong language.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
return router.query.site === singleSite?.properties.id; | ||
}); | ||
if (siteIndex === -1) { | ||
router.push(`/projects-archive/${project.slug}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include locale
in the redirect path
In line 183, when redirecting, the path does not include the locale
, which could lead to incorrect routing in a multi-language setup.
Update the redirect path to include the locale
:
- router.push(`/projects-archive/${project.slug}`);
+ router.push(`/${locale}/projects-archive/${project.slug}`);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
router.push(`/projects-archive/${project.slug}`); | |
router.push(`/${locale}/projects-archive/${project.slug}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add this as an issue, along with similar points. I'll address this later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mohitb35, I've opened a new GitHub issue regarding the missing locale
in redirect paths and similar points for you to address later. You can find it here: Issue #2299.
🔗 Analysis chain
@mohitb35, I've opened a new GitHub issue with this point and similar ones for you to address later.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Create a new GitHub issue regarding missing 'locale' in redirect paths
gh issue create \
--title "Missing 'locale' in redirect paths leading to incorrect routing" \
--body "There are instances in the codebase where the 'locale' parameter is not included in redirect paths, which could lead to incorrect routing in a multi-language setup.
Reference: PR [#2296](https://github.com/Plant-for-the-Planet-org/planet-webapp/pull/2296) and [this comment](https://github.com/Plant-for-the-Planet-org/planet-webapp/pull/2296#discussion_r1832677708).
@mojitb35" \
--assignee mohitb35
Length of output: 582
}); | ||
|
||
if (singlePlantLocation === undefined) { | ||
router.push(`/projects-archive/${project.slug}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include locale
in the redirect path
Similarly, in line 199, the redirect path lacks the locale
, which is important for proper localization.
Adjust the redirect path:
- router.push(`/projects-archive/${project.slug}`);
+ router.push(`/${locale}/projects-archive/${project.slug}`);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
router.push(`/projects-archive/${project.slug}`); | |
router.push(`/${locale}/projects-archive/${project.slug}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add this as an issue, along with similar points. I'll address this later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mohitb35, I have created an issue to track this, along with the similar points. You can find it here: #2298
🔗 Analysis chain
@mohitb35, I'll create an issue to track this, along with the similar points.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Create a GitHub issue to track inclusion of 'locale' in redirect paths
gh issue create \
--title "Include 'locale' in redirect paths for proper localization" \
--body "As discussed in [PR #2296](https://github.com/Plant-for-the-Planet-org/planet-webapp/pull/2296), there are instances where redirect paths lack the \`locale\`, which is essential for proper localization. This issue aims to update all redirect paths to include the \`locale\` parameter.
Referenced from [this comment](https://github.com/Plant-for-the-Planet-org/planet-webapp/pull/2296#discussion_r1832677709) by @mohitb35." \
--assignee mohitb35
Length of output: 610
React.useEffect(() => { | ||
//for selecting one of the site of project if user use link to directly visit to site from home page | ||
if (project && geoJson && router.query.site) { | ||
const siteIndex: number = geoJson?.features.findIndex((singleSite) => { | ||
return router.query.site === singleSite?.properties.id; | ||
}); | ||
if (siteIndex === -1) { | ||
router.push(`/projects-archive/${project.slug}`); | ||
} else { | ||
setSelectedSite(siteIndex); | ||
} | ||
} | ||
}, [setSelectedSite, geoJson, project]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include router.query.site
in the dependencies of useEffect
The useEffect
hook starting at line 176 uses router.query.site
but doesn't list it in the dependencies array. This may prevent the effect from running when router.query.site
updates.
Update the dependencies array to include router.query.site
:
- }, [setSelectedSite, geoJson, project]);
+ }, [setSelectedSite, geoJson, project, router.query.site]);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
React.useEffect(() => { | |
//for selecting one of the site of project if user use link to directly visit to site from home page | |
if (project && geoJson && router.query.site) { | |
const siteIndex: number = geoJson?.features.findIndex((singleSite) => { | |
return router.query.site === singleSite?.properties.id; | |
}); | |
if (siteIndex === -1) { | |
router.push(`/projects-archive/${project.slug}`); | |
} else { | |
setSelectedSite(siteIndex); | |
} | |
} | |
}, [setSelectedSite, geoJson, project]); | |
React.useEffect(() => { | |
//for selecting one of the site of project if user use link to directly visit to site from home page | |
if (project && geoJson && router.query.site) { | |
const siteIndex: number = geoJson?.features.findIndex((singleSite) => { | |
return router.query.site === singleSite?.properties.id; | |
}); | |
if (siteIndex === -1) { | |
router.push(`/projects-archive/${project.slug}`); | |
} else { | |
setSelectedSite(siteIndex); | |
} | |
} | |
}, [setSelectedSite, geoJson, project, router.query.site]); |
React.useEffect(() => { | ||
//for selecting one of the plant location. if user use link to directly visit to plantLocation from home page | ||
if (geoJson && router.query.ploc && plantLocations && project) { | ||
const singlePlantLocation: PlantLocation | undefined = | ||
plantLocations?.find((singlePlantLocation) => { | ||
return router.query.ploc === singlePlantLocation?.hid; | ||
}); | ||
|
||
if (singlePlantLocation === undefined) { | ||
router.push(`/projects-archive/${project.slug}`); | ||
} else { | ||
setSelectedPl(singlePlantLocation); | ||
} | ||
} | ||
}, [router, router.query.ploc, plantLocations, setSelectedPl, project]); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid using the entire router
object in dependencies
Including the whole router
object in the dependencies array at line 190 can cause unnecessary re-renders since the router object may change on every render. It's better to specify only the needed properties.
Modify the dependencies to include specific properties:
- }, [router, router.query.ploc, plantLocations, setSelectedPl, project]);
+ }, [router.query.ploc, plantLocations, setSelectedPl, project]);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
React.useEffect(() => { | |
//for selecting one of the plant location. if user use link to directly visit to plantLocation from home page | |
if (geoJson && router.query.ploc && plantLocations && project) { | |
const singlePlantLocation: PlantLocation | undefined = | |
plantLocations?.find((singlePlantLocation) => { | |
return router.query.ploc === singlePlantLocation?.hid; | |
}); | |
if (singlePlantLocation === undefined) { | |
router.push(`/projects-archive/${project.slug}`); | |
} else { | |
setSelectedPl(singlePlantLocation); | |
} | |
} | |
}, [router, router.query.ploc, plantLocations, setSelectedPl, project]); | |
React.useEffect(() => { | |
//for selecting one of the plant location. if user use link to directly visit to plantLocation from home page | |
if (geoJson && router.query.ploc && plantLocations && project) { | |
const singlePlantLocation: PlantLocation | undefined = | |
plantLocations?.find((singlePlantLocation) => { | |
return router.query.ploc === singlePlantLocation?.hid; | |
}); | |
if (singlePlantLocation === undefined) { | |
router.push(`/projects-archive/${project.slug}`); | |
} else { | |
setSelectedPl(singlePlantLocation); | |
} | |
} | |
}, [router.query.ploc, plantLocations, setSelectedPl, project]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add this as an issue, will take care of it later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mohitb35, I've opened a new GitHub issue to track this: #2300.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Open a new GitHub issue to track the suggested change
gh issue create \
--title "Avoid using the entire router object in dependencies" \
--body "As discussed in [PR #2296](https://github.com/Plant-for-the-Planet-org/planet-webapp/pull/2296), it's recommended to avoid including the entire \`router\` object in the dependencies array in \`pages/sites/[slug]/[locale]/projects-archive/[p].tsx\` at line 190. Instead, specify only the needed properties to prevent unnecessary re-renders.
[Comment reference](https://github.com/Plant-for-the-Planet-org/planet-webapp/pull/2296#discussion_r1832677716)" \
--assignee mohitb35
Length of output: 631
React.useEffect(() => { | ||
async function loadProject() { | ||
if ( | ||
!internalCurrencyCode || | ||
currencyCode !== internalCurrencyCode || | ||
internalLanguage !== locale | ||
) { | ||
const currency = getStoredCurrency( | ||
pageProps.tenantConfig.config.fallbackCurrency! | ||
); | ||
setInternalCurrencyCode(currency); | ||
setInternalLanguage(locale); | ||
setCurrencyCode(currency); | ||
try { | ||
const { p } = router.query; | ||
const project = await getRequest<ProjectExtended>( | ||
pageProps.tenantConfig.id, | ||
encodeURI(`/app/projects/${p}`), | ||
{ | ||
_scope: 'extended', | ||
currency: currency || '', | ||
locale: locale, | ||
} | ||
); | ||
if ( | ||
project.purpose === 'conservation' || | ||
project.purpose === 'trees' | ||
) { | ||
setProject(project); | ||
setShowSingleProject(true); | ||
setZoomLevel(2); | ||
} else { | ||
throw new ClientError(404, { | ||
error_type: 'project_not_available', | ||
error_code: 'project_not_available', | ||
}); | ||
} | ||
} catch (err) { | ||
setErrors(handleError(err as APIError | ClientError)); | ||
redirect('/'); | ||
} | ||
} | ||
} | ||
if (router.query.p) { | ||
loadProject(); | ||
} | ||
}, [router.query.p, currencyCode, locale]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add missing dependencies to the useEffect
hook
In the useEffect
starting at line 81, the dependencies array does not include internalCurrencyCode
and internalLanguage
, which are used inside the effect. This could lead to stale values or unintended behavior.
Consider adding internalCurrencyCode
and internalLanguage
to the dependencies array:
- }, [router.query.p, currencyCode, locale]);
+ }, [router.query.p, currencyCode, locale, internalCurrencyCode, internalLanguage]);
Alternatively, refactor the logic to avoid potential infinite loops if these values change frequently.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
React.useEffect(() => { | |
async function loadProject() { | |
if ( | |
!internalCurrencyCode || | |
currencyCode !== internalCurrencyCode || | |
internalLanguage !== locale | |
) { | |
const currency = getStoredCurrency( | |
pageProps.tenantConfig.config.fallbackCurrency! | |
); | |
setInternalCurrencyCode(currency); | |
setInternalLanguage(locale); | |
setCurrencyCode(currency); | |
try { | |
const { p } = router.query; | |
const project = await getRequest<ProjectExtended>( | |
pageProps.tenantConfig.id, | |
encodeURI(`/app/projects/${p}`), | |
{ | |
_scope: 'extended', | |
currency: currency || '', | |
locale: locale, | |
} | |
); | |
if ( | |
project.purpose === 'conservation' || | |
project.purpose === 'trees' | |
) { | |
setProject(project); | |
setShowSingleProject(true); | |
setZoomLevel(2); | |
} else { | |
throw new ClientError(404, { | |
error_type: 'project_not_available', | |
error_code: 'project_not_available', | |
}); | |
} | |
} catch (err) { | |
setErrors(handleError(err as APIError | ClientError)); | |
redirect('/'); | |
} | |
} | |
} | |
if (router.query.p) { | |
loadProject(); | |
} | |
}, [router.query.p, currencyCode, locale]); | |
React.useEffect(() => { | |
async function loadProject() { | |
if ( | |
!internalCurrencyCode || | |
currencyCode !== internalCurrencyCode || | |
internalLanguage !== locale | |
) { | |
const currency = getStoredCurrency( | |
pageProps.tenantConfig.config.fallbackCurrency! | |
); | |
setInternalCurrencyCode(currency); | |
setInternalLanguage(locale); | |
setCurrencyCode(currency); | |
try { | |
const { p } = router.query; | |
const project = await getRequest<ProjectExtended>( | |
pageProps.tenantConfig.id, | |
encodeURI(`/app/projects/${p}`), | |
{ | |
_scope: 'extended', | |
currency: currency || '', | |
locale: locale, | |
} | |
); | |
if ( | |
project.purpose === 'conservation' || | |
project.purpose === 'trees' | |
) { | |
setProject(project); | |
setShowSingleProject(true); | |
setZoomLevel(2); | |
} else { | |
throw new ClientError(404, { | |
error_type: 'project_not_available', | |
error_code: 'project_not_available', | |
}); | |
} | |
} catch (err) { | |
setErrors(handleError(err as APIError | ClientError)); | |
redirect('/'); | |
} | |
} | |
} | |
if (router.query.p) { | |
loadProject(); | |
} | |
}, [router.query.p, currencyCode, locale, internalCurrencyCode, internalLanguage]); |
/
and/[p]
- removing the temporary/prd
prefix/projects-archive
and/projects-archive/[p]
until the old projects code can be removed