diff --git a/.env.local.example b/.env.local.example index fbf5658f..7381629e 100644 --- a/.env.local.example +++ b/.env.local.example @@ -25,7 +25,18 @@ SENTRY_DSN_URL=https://sentrydsnurl NEXT_PUBLIC_SENTRY_DSN_URL=https://sentrydsnurl SENTRY_ORG_NAME='orgname' SENTRY_PROJECT_NAME='projectname' -NEXT_PUBLIC_PLATFORM_URL = 'https://platformurl' +NEXT_PUBLIC_PLATFORM_URL=https://platformurl + +# Domain used for slug subdomains (recommended to set explicitly) +# Local : localhost +# Dev : dev.civicdataspace.in +# Prod : civicdataspace.in +NEXT_PUBLIC_PLATFORM_DOMAIN=platformdomain + +# Optional: set protocol/port explicitly for slug subdomain URLs +NEXT_PUBLIC_PLATFORM_PROTOCOL=https +NEXT_PUBLIC_PLATFORM_PORT=3000 + # Google Analytics NEXT_PUBLIC_GA_ID='G-XXXXXXXXXX' diff --git a/.github/workflows/deploy-Dataspace-dev.yml b/.github/workflows/deploy-Dataspace-dev.yml deleted file mode 100644 index 6c4801d6..00000000 --- a/.github/workflows/deploy-Dataspace-dev.yml +++ /dev/null @@ -1,81 +0,0 @@ -name: Update DataSpace Dev - -on: - push: - branches: ['dev'] - -jobs: - deploy: - runs-on: ubuntu-latest - environment: development - env: - KEYCLOAK_CLIENT_ID: ${{ secrets.KEYCLOAK_CLIENT_ID }} - KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} - AUTH_ISSUER: ${{ secrets.AUTH_ISSUER }} - NEXTAUTH_URL: ${{ vars.NEXTAUTH_URL }} - NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }} - NEXT_PUBLIC_NEXTAUTH_URL: ${{ vars.NEXT_PUBLIC_NEXTAUTH_URL }} - END_SESSION_URL: ${{ secrets.END_SESSION_URL }} - REFRESH_TOKEN_URL: ${{ secrets.REFRESH_TOKEN_URL }} - NEXT_PUBLIC_BACKEND_URL: ${{ vars.NEXT_PUBLIC_BACKEND_URL }} - BACKEND_URL: ${{ vars.BACKEND_URL }} - NEXT_PUBLIC_BACKEND_GRAPHQL_URL: ${{ vars.NEXT_PUBLIC_BACKEND_GRAPHQL_URL }} - BACKEND_GRAPHQL_URL: ${{ vars.BACKEND_GRAPHQL_URL }} - NEXT_PUBLIC_ENABLE_ACCESSMODEL: ${{ vars.NEXT_PUBLIC_ENABLE_ACCESSMODEL }} - NEXT_PUBLIC_ANALYTICS_URL: ${{ vars.NEXT_PUBLIC_ANALYTICS_URL }} - NEXT_PUBLIC_PLATFORM_URL: ${{ vars.NEXT_PUBLIC_PLATFORM_URL }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - - - name: Install dependencies - run: npm install --legacy-peer-deps - - - name: Generate - run: npm run generate:ci - env: - BACKEND_GRAPHQL_URL: ${{ vars.BACKEND_GRAPHQL_URL }} - NODE_ENV: production - - - name: Build - run: npm run build - - - name: Rename .next to .next2 - run: mv .next .next2 - - - name: Rename public to public2 - run: mv public public2 - - - name: Send .next2 to EC2 - uses: appleboy/scp-action@v0.1.7 - with: - host: ${{ vars.EC2_HOST }} - username: ${{ secrets.EC2_USERNAME }} - key: ${{ secrets.EC2_PRIVATE_KEY }} - source: .next2 - target: DataExchange/DataExFrontend - - - name: Send public2 to EC2 - uses: appleboy/scp-action@v0.1.7 - with: - host: ${{ vars.EC2_HOST }} - username: ${{ secrets.EC2_USERNAME }} - key: ${{ secrets.EC2_PRIVATE_KEY }} - source: public2 - target: DataExchange/DataExFrontend - - - name: Update with new Build - uses: appleboy/ssh-action@v1.0.3 - continue-on-error: false - with: - host: ${{ vars.EC2_HOST }} - username: ${{ secrets.EC2_USERNAME }} - key: ${{ secrets.EC2_PRIVATE_KEY }} - script: rm -rf DataExchange/DataExFrontend/.next; rm -rf DataExchange/DataExFrontend/public; mv DataExchange/DataExFrontend/.next2 DataExchange/DataExFrontend/.next; mv DataExchange/DataExFrontend/public2 DataExchange/DataExFrontend/public; /home/ubuntu/.nvm/versions/node/v20.11.1/bin/pm2 restart dataspace diff --git a/.github/workflows/deploy-Dataspace.yml b/.github/workflows/deploy-Dataspace.yml index 0bf47fa5..65985553 100644 --- a/.github/workflows/deploy-Dataspace.yml +++ b/.github/workflows/deploy-Dataspace.yml @@ -1,38 +1,52 @@ -name: Update DataSpace Prod +name: Deploy DataSpace on: push: - branches: ['main'] -env: - KEYCLOAK_CLIENT_ID: ${{secrets.KEYCLOAK_CLIENT_ID}} - KEYCLOAK_CLIENT_SECRET: ${{secrets.KEYCLOAK_CLIENT_SECRET}} - AUTH_ISSUER: ${{secrets.AUTH_ISSUER}} - NEXTAUTH_URL: ${{secrets.NEXTAUTH_URL_DS}} - NEXT_PUBLIC_NEXTAUTH_URL: ${{secrets.NEXT_PUBLIC_NEXTAUTH_URL_DS}} - NEXTAUTH_SECRET: ${{secrets.NEXTAUTH_SECRET}} - END_SESSION_URL: ${{secrets.END_SESSION_URL}} - REFRESH_TOKEN_URL: ${{secrets.REFRESH_TOKEN_URL}} - NEXT_PUBLIC_BACKEND_URL: ${{secrets.NEXT_PUBLIC_BACKEND_URL_DS}} - BACKEND_GRAPHQL_URL: ${{secrets.BACKEND_GRAPHQL_URL_DS}} - NEXT_PUBLIC_ENABLE_ACCESSMODEL: ${{secrets.NEXT_PUBLIC_ENABLE_ACCESSMODEL_DS}} - NEXT_PUBLIC_BACKEND_GRAPHQL_URL: ${{secrets.NEXT_PUBLIC_BACKEND_GRAPHQL_URL_DS}} - BACKEND_URL: ${{secrets.BACKEND_URL}} - NEXT_PUBLIC_PLATFORM_URL: ${{secrets.NEXT_PUBLIC_PLATFORM_URL}} - NEXT_PUBLIC_ANALYTICS_URL: ${{secrets.NEXT_PUBLIC_ANALYTICS_URL}} + branches: + - dev + - main jobs: deploy: runs-on: ubuntu-latest + environment: ${{ github.ref_name == 'main' && 'production' || 'development' }} + env: + KEYCLOAK_CLIENT_ID: ${{ secrets.KEYCLOAK_CLIENT_ID }} + KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} + AUTH_ISSUER: ${{ secrets.AUTH_ISSUER }} + NEXTAUTH_URL: ${{ vars.NEXTAUTH_URL }} + NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }} + NEXT_PUBLIC_NEXTAUTH_URL: ${{ vars.NEXT_PUBLIC_NEXTAUTH_URL }} + END_SESSION_URL: ${{ secrets.END_SESSION_URL }} + REFRESH_TOKEN_URL: ${{ secrets.REFRESH_TOKEN_URL }} + NEXT_PUBLIC_BACKEND_URL: ${{ vars.NEXT_PUBLIC_BACKEND_URL }} + BACKEND_URL: ${{ vars.BACKEND_URL }} + NEXT_PUBLIC_BACKEND_GRAPHQL_URL: ${{ vars.NEXT_PUBLIC_BACKEND_GRAPHQL_URL }} + BACKEND_GRAPHQL_URL: ${{ vars.BACKEND_GRAPHQL_URL }} + NEXT_PUBLIC_ENABLE_ACCESSMODEL: ${{ vars.NEXT_PUBLIC_ENABLE_ACCESSMODEL }} + NEXT_PUBLIC_ANALYTICS_URL: ${{ vars.NEXT_PUBLIC_ANALYTICS_URL }} + NEXT_PUBLIC_PLATFORM_URL: ${{ vars.NEXT_PUBLIC_PLATFORM_URL }} + NEXT_PUBLIC_PLATFORM_PROTOCOL: ${{ vars.NEXT_PUBLIC_PLATFORM_PROTOCOL }} + NEXT_PUBLIC_PLATFORM_DOMAIN: ${{ vars.NEXT_PUBLIC_PLATFORM_DOMAIN }} steps: - name: Checkout code uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + - name: Install dependencies - run: npm install + run: npm install --legacy-peer-deps - name: Generate - run: npm run generate + run: npm run generate:ci + env: + BACKEND_GRAPHQL_URL: ${{ vars.BACKEND_GRAPHQL_URL }} + NODE_ENV: production - name: Build run: npm run build @@ -41,30 +55,31 @@ jobs: run: mv .next .next2 - name: Rename public to public2 - run: mv public public2 + run: mv public public2 - name: Send .next2 to EC2 - uses: appleboy/scp-action@master + uses: appleboy/scp-action@v0.1.7 with: - host: ${{ secrets.EC2_HOST_DS }} - username: ${{ secrets.EC2_USERNAME_DS }} + host: ${{ vars.EC2_HOST }} + username: ${{ secrets.EC2_USERNAME }} key: ${{ secrets.EC2_PRIVATE_KEY }} source: .next2 target: DataExchange/DataExFrontend - name: Send public2 to EC2 - uses: appleboy/scp-action@master + uses: appleboy/scp-action@v0.1.7 with: - host: ${{ secrets.EC2_HOST_DS }} - username: ${{ secrets.EC2_USERNAME_DS }} + host: ${{ vars.EC2_HOST }} + username: ${{ secrets.EC2_USERNAME }} key: ${{ secrets.EC2_PRIVATE_KEY }} source: public2 - target: DataExchange/DataExFrontend - + target: DataExchange/DataExFrontend + - name: Update with new Build uses: appleboy/ssh-action@v1.0.3 + continue-on-error: false with: - host: ${{ secrets.EC2_HOST_DS }} - username: ${{ secrets.EC2_USERNAME_DS }} + host: ${{ vars.EC2_HOST }} + username: ${{ secrets.EC2_USERNAME }} key: ${{ secrets.EC2_PRIVATE_KEY }} script: rm -rf DataExchange/DataExFrontend/.next; rm -rf DataExchange/DataExFrontend/public; mv DataExchange/DataExFrontend/.next2 DataExchange/DataExFrontend/.next; mv DataExchange/DataExFrontend/public2 DataExchange/DataExFrontend/public; /home/ubuntu/.nvm/versions/node/v20.11.1/bin/pm2 restart dataspace diff --git a/.github/workflows/pre-merge.yml b/.github/workflows/pre-merge.yml index 3f81b490..0df80218 100644 --- a/.github/workflows/pre-merge.yml +++ b/.github/workflows/pre-merge.yml @@ -6,7 +6,6 @@ on: pull_request: branches: ['dev'] - jobs: build: runs-on: ubuntu-latest @@ -27,6 +26,8 @@ jobs: BACKEND_URL: ${{vars.BACKEND_URL}} NEXT_PUBLIC_PLATFORM_URL: ${{vars.NEXT_PUBLIC_PLATFORM_URL}} NEXT_PUBLIC_ANALYTICS_URL: ${{vars.NEXT_PUBLIC_ANALYTICS_URL}} + NEXT_PUBLIC_PLATFORM_PROTOCOL: ${{ vars.NEXT_PUBLIC_PLATFORM_PROTOCOL }} + NEXT_PUBLIC_PLATFORM_DOMAIN: ${{ vars.NEXT_PUBLIC_PLATFORM_DOMAIN }} strategy: matrix: node-version: [20.x] diff --git a/app/[locale]/(user)/collaboratives/CollaborativesListingClient.tsx b/app/[locale]/(user)/collaboratives/CollaborativesListingClient.tsx index 3e5c4904..f7cefb3a 100644 --- a/app/[locale]/(user)/collaboratives/CollaborativesListingClient.tsx +++ b/app/[locale]/(user)/collaboratives/CollaborativesListingClient.tsx @@ -8,6 +8,7 @@ import { useQuery } from '@tanstack/react-query'; import { Button, Card, Icon, SearchInput, Select, Text } from 'opub-ui'; import { GraphQLPublic } from '@/lib/api'; +import { getCollaborativeDetailUrl } from '@/lib/collaborativesRouting'; import { cn, formatDate, generateJsonLd } from '@/lib/utils'; import BreadCrumbs from '@/components/BreadCrumbs'; import { Icons } from '@/components/icons'; @@ -97,7 +98,7 @@ const CollaborativesListingClient = () => { try { // @ts-expect-error - Query has no variables const result = await GraphQLPublic(PublishedCollaboratives as any, {}); - console.log('Collaboratives result:', result); + // console.log('Collaboratives result:', result); return result as { publishedCollaboratives: TypeCollaborative[] }; } catch (err) { console.error('Error fetching collaboratives:', err); @@ -336,7 +337,7 @@ const CollaborativesListingClient = () => { stroke: 1.2, }, ]} - href={`/collaboratives/${collaborative.slug}`} + href={getCollaborativeDetailUrl(collaborative.slug)} leftFooterChips={[ { icon: collaborative.sectors?.[0]?.name diff --git a/app/[locale]/(user)/collaboratives/[collaborativeSlug]/CollaborativeDetailsClient.tsx b/app/[locale]/(user)/collaboratives/[collaborativeSlug]/CollaborativeDetailsClient.tsx index 5112b762..f7a84cad 100644 --- a/app/[locale]/(user)/collaboratives/[collaborativeSlug]/CollaborativeDetailsClient.tsx +++ b/app/[locale]/(user)/collaboratives/[collaborativeSlug]/CollaborativeDetailsClient.tsx @@ -1,6 +1,6 @@ 'use client'; -import { useEffect } from 'react'; +import { useEffect, useState } from 'react'; import Image from 'next/image'; import Link from 'next/link'; import { useParams } from 'next/navigation'; @@ -15,6 +15,7 @@ import { useQuery } from '@tanstack/react-query'; import { Card, Text } from 'opub-ui'; import { GraphQLPublic } from '@/lib/api'; +import { isCollaborativeSubdomainHost as isCollaborativeSubdomainHostname } from '@/lib/collaborativesRouting'; import { formatDate, generateJsonLd } from '@/lib/utils'; import BreadCrumbs from '@/components/BreadCrumbs'; import { Icons } from '@/components/icons'; @@ -217,9 +218,41 @@ const CollaborativeDetails = graphql(` } `); +const getPlatformEntityUrl = ( + entityPath: 'usecases' | 'datasets', + entityId: string | number, + locale?: string +) => { + //Removes trailing slash + const platformBaseUrl = (process.env.NEXT_PUBLIC_PLATFORM_URL || '').replace( + /\/$/, + '' + ); + const localeSegment = locale ? `/${locale}` : ''; + + if (!platformBaseUrl) { + return `/${entityPath}/${entityId}`; + } + + return `${platformBaseUrl}${localeSegment}/${entityPath}/${entityId}`; +}; + const CollaborativeDetailClient = () => { const params = useParams(); const { trackCollaborative } = useAnalytics(); + const locale = + typeof (params as any)?.locale === 'string' + ? (params as any).locale + : undefined; + const [isCollaborativeSubdomainHost, setIsCollaborativeSubdomainHost] = + useState(false); + + useEffect(() => { + if (typeof window === 'undefined') return; + setIsCollaborativeSubdomainHost( + isCollaborativeSubdomainHostname(window.location.hostname) + ); + }, []); const { data: CollaborativeDetailsData, @@ -250,12 +283,6 @@ const CollaborativeDetailClient = () => { } ); - console.log('Collaborative details query state:', { - isLoading, - error, - data: CollaborativeDetailsData, - }); - // Track collaborative view when data is loaded useEffect(() => { if (CollaborativeDetailsData?.collaborativeBySlug) { @@ -295,6 +322,17 @@ const CollaborativeDetailClient = () => { }, }); + const organizationPublisherHref = (org: any) => { + const path = `/publishers/organization/${org.id}`; + // Original: `/publishers/organization/${org.slug + '_' + org.id}`; + // Match getPlatformEntityUrl() behavior (absolute to platform host + locale) + const platformBaseUrl = ( + process.env.NEXT_PUBLIC_PLATFORM_URL || '' + ).replace(/\/$/, ''); + const localeSegment = locale ? `/${locale}` : ''; + return platformBaseUrl ? `${platformBaseUrl}${localeSegment}${path}` : path; + }; + return ( <> @@ -328,20 +366,23 @@ const CollaborativeDetailClient = () => { ) : ( <> - + {!isCollaborativeSubdomainHost && ( + + )}
-
+
{ {CollaborativeDetailsData?.collaborativeBySlug?.supportingOrganizations?.map( (org: any) => (
@@ -390,7 +431,7 @@ const CollaborativeDetailClient = () => { {CollaborativeDetailsData?.collaborativeBySlug?.partnerOrganizations?.map( (org: any) => (
@@ -415,7 +456,10 @@ const CollaborativeDetailClient = () => {
{/* Use Cases Section */} {useCases.length > 0 && ( -
+
Use Cases @@ -499,7 +543,11 @@ const CollaborativeDetailClient = () => { key={useCase.id} variation={'collapsed'} iconColor="success" - href={`/usecases/${useCase.id}`} + href={getPlatformEntityUrl( + 'usecases', + useCase.id, + locale + )} /> ); })} @@ -507,7 +555,10 @@ const CollaborativeDetailClient = () => {
)} {/* Datasets Section */} -
+
Datasets in this Collaborative @@ -550,7 +601,11 @@ const CollaborativeDetailClient = () => { stroke: 1.2, }, ]} - href={`/datasets/${dataset.id}`} + href={getPlatformEntityUrl( + 'datasets', + dataset.id, + locale + )} leftFooterChips={[ { icon: `/Sectors/${dataset.sectors[0]?.name}.svg`, diff --git a/app/[locale]/(user)/collaboratives/components/Metadata.tsx b/app/[locale]/(user)/collaboratives/components/Metadata.tsx index f1849d9d..bd7ea924 100644 --- a/app/[locale]/(user)/collaboratives/components/Metadata.tsx +++ b/app/[locale]/(user)/collaboratives/components/Metadata.tsx @@ -1,10 +1,11 @@ +import { useEffect, useState } from 'react'; import Image from 'next/image'; import Link from 'next/link'; import { Button, Icon, Text, Tooltip } from 'opub-ui'; -import { useEffect, useState } from 'react'; -import { Icons } from '@/components/icons'; +import { getPlatformRootUrl } from '@/lib/collaborativesRouting'; import { formatDate, getWebsiteTitle } from '@/lib/utils'; +import { Icons } from '@/components/icons'; const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { const [platformTitle, setPlatformTitle] = useState(null); @@ -32,7 +33,7 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { const metadata = [ { - label: 'Platform URL', + label: 'External Link', value: data.collaborativeBySlug.platformUrl === null ? ( 'N/A' @@ -41,12 +42,16 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { className="text-primaryBlue underline lg:text-white" href={data.collaborativeBySlug.platformUrl} > - - {platformTitle?.trim() ? platformTitle : 'Visit Platform'} + + {platformTitle?.trim() ? platformTitle : 'Open Link'} ), - tooltipContent: data.collaborativeBySlug.platformUrl === null ? 'N/A' : platformTitle, + tooltipContent: + data.collaborativeBySlug.platformUrl === null ? 'N/A' : platformTitle, }, { label: 'Last Updated', @@ -58,17 +63,19 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { value: (
{data.collaborativeBySlug.sectors.length > 0 ? ( - data.collaborativeBySlug.sectors.map((sector: any, index: number) => ( - - {sector.name - - )) + data.collaborativeBySlug.sectors.map( + (sector: any, index: number) => ( + + {sector.name + + ) + ) ) : ( N/A // Fallback if no sectors are available )} @@ -79,7 +86,8 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { label: 'SDG Goals', value: (
- {data.collaborativeBySlug.sdgs && data.collaborativeBySlug.sdgs.length > 0 ? ( + {data.collaborativeBySlug.sdgs && + data.collaborativeBySlug.sdgs.length > 0 ? ( data.collaborativeBySlug.sdgs.map((sdg: any, index: number) => ( { ), }, ]; - + // Use collaborative logo if available, otherwise use a default const image = data.collaborativeBySlug?.logo?.path ? `${process.env.NEXT_PUBLIC_BACKEND_URL}/${data.collaborativeBySlug.logo.path.replace('/code/files/', '')}` : '/org.png'; + const platformRootUrl = getPlatformRootUrl(); + const getLocaleSegment = () => { + if (typeof window === 'undefined') return ''; + const match = window.location.pathname.match(/^\/([a-z]{2})(\/|$)/i); + return match ? `/${match[1].toLowerCase()}` : ''; + }; + const contributorHref = (contributor: any) => { + const path = `/publishers/${contributor.id}`; + // Original: `/publishers/${contributor.fullName + '_' + contributor.id}`; + // Match getPlatformEntityUrl() behavior (absolute to NEXT_PUBLIC_PLATFORM_URL + locale) + const platformBaseUrl = ( + process.env.NEXT_PUBLIC_PLATFORM_URL || '' + ).replace(/\/$/, ''); + const localeSegment = getLocaleSegment(); + if (platformBaseUrl) return `${platformBaseUrl}${localeSegment}${path}`; + + return platformRootUrl === '/' ? path : `${platformRootUrl}${path}`; + }; + return (
@@ -115,7 +142,9 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { > ABOUT THE COLLABORATIVE{' '} - DETAILS + + DETAILS +
{setOpen && ( @@ -125,7 +154,7 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { )}
-
+
{ {metadata.map((item, index) => (
{item.label} @@ -157,38 +186,41 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => {
))} {/* Contributors Section */} - {data.collaborativeBySlug.contributors && data.collaborativeBySlug.contributors.length > 0 && ( -
- - Contributors - -
- {data.collaborativeBySlug.contributors.map((contributor: any) => ( - - - {contributor.fullName} - - - ))} + {data.collaborativeBySlug.contributors && + data.collaborativeBySlug.contributors.length > 0 && ( +
+ + Contributors + +
+ {data.collaborativeBySlug.contributors.map( + (contributor: any) => ( + + + {contributor.fullName} + + + ) + )} +
-
- )} + )}
diff --git a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Metadata/index.tsx b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Metadata/index.tsx index 9c9dd583..205ae8b6 100644 --- a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Metadata/index.tsx +++ b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Metadata/index.tsx @@ -83,11 +83,11 @@ const MetadataComponent: React.FC = ({ data, setOpen }) => { if (!data) return '/publishers'; if (data.isIndividualDataset && data.user) { - return `/publishers/${data.user.fullName + '_' + data.user.id}`; + return `/publishers/${data.user.id}`; } if (data.organization) { - return `/publishers/organization/${data.organization.slug + '_' + data.organization.id}`; + return `/publishers/organization/${data.organization.id}`; } return '/publishers'; diff --git a/app/[locale]/(user)/layout.tsx b/app/[locale]/(user)/layout.tsx index 29f8f885..fb4a462f 100644 --- a/app/[locale]/(user)/layout.tsx +++ b/app/[locale]/(user)/layout.tsx @@ -1,10 +1,12 @@ 'use client'; import { notFound, usePathname } from 'next/navigation'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import MainFooter from '../dashboard/components/main-footer'; import { MainNav } from '../dashboard/components/main-nav'; +import { CollaborativeSubdomainNav } from '../dashboard/components/CollaborativeSubdomainNav'; +import { isCollaborativeSubdomainHost } from '@/lib/collaborativesRouting'; interface UserLayoutProps { children?: React.ReactNode; @@ -14,16 +16,41 @@ export default function Layout({ children }: UserLayoutProps) { const user = true; // await getCurrentUser() const routerPath = usePathname(); const hideSearch = routerPath === '/' || routerPath === '/datasets'; + const [isCollaborativeSubdomain, setIsCollaborativeSubdomain] = useState< + boolean | null + >(null); + const shouldHideMainNav = isCollaborativeSubdomain === true; + + useEffect(() => { + if (typeof window === 'undefined') { + setIsCollaborativeSubdomain(false); + return; + } + + setIsCollaborativeSubdomain( + isCollaborativeSubdomainHost(window.location.hostname) + ); + }, [routerPath]); if (!user) { return notFound(); } + const shouldRenderMainNav = + isCollaborativeSubdomain !== null && !shouldHideMainNav; + const shouldRenderCollaborativeSubdomainNav = isCollaborativeSubdomain === true; + return (
-
- -
+ {isCollaborativeSubdomain !== null && ( +
+ {shouldRenderMainNav ? ( + + ) : shouldRenderCollaborativeSubdomainNav ? ( + + ) : null} +
+ )}
{children}