diff --git a/app/[locale]/(user)/components/ListingComponent.tsx b/app/[locale]/(user)/components/ListingComponent.tsx index 307f99a3..2898fc68 100644 --- a/app/[locale]/(user)/components/ListingComponent.tsx +++ b/app/[locale]/(user)/components/ListingComponent.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useReducer, useState } from 'react'; +import React, { useEffect, useReducer, useRef, useState } from 'react'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; import GraphqlPagination from '@/app/[locale]/dashboard/components/GraphqlPagination/graphqlPagination'; @@ -219,12 +219,18 @@ const ListingComponent: React.FC = ({ const datasetDetails = facets?.results ?? []; useUrlParams(queryParams, setQueryParams, setVariables); + const latestFetchId = useRef(0); useEffect(() => { if (variables) { + const currentFetchId = ++latestFetchId.current; + fetchDatasets(variables) .then((res) => { - setFacets(res); + // Only set if this is the latest call + if (currentFetchId === latestFetchId.current) { + setFacets(res); + } }) .catch((err) => { console.error(err); @@ -471,36 +477,71 @@ const ListingComponent: React.FC = ({ : item?.organization?.logo ? `${process.env.NEXT_PUBLIC_BACKEND_URL}/${item.organization.logo}` : '/org.png'; + const Geography = item.metadata.filter( + (item: any) => item.metadata_item.label === 'Geography' + )[0]?.value; + + const MetadataContent = [ + { + icon: Icons.calendar, + label: 'Date', + value: formatDate(item.modified), + tooltip: 'Date', + }, + { + icon: Icons.download, + label: 'Download', + value: item.download_count.toString(), + tooltip: 'Download', + }, + ]; + if (Geography) { + MetadataContent.push({ + icon: Icons.globe, + label: 'Geography', + value: Geography, + tooltip: 'Geography', + }); + } + + if (item.has_charts && view === 'expanded') { + MetadataContent.push({ + icon: Icons.chart, + label: '', + value: 'With Charts', + tooltip: 'Charts', + }); + } + + const FooterContent = [ + { + icon: `/Sectors/${item.sectors[0]}.svg`, + label: 'Sectors', + tooltip: `${item.sectors[0]}`, + }, + ...(item.has_charts && view !== 'expanded' + ? [ + { + icon: `/chart-bar.svg`, + label: 'Charts', + tooltip: 'Charts', + }, + ] + : []), + { + icon: image, + label: 'Published by', + tooltip: `${item.is_individual_dataset ? item.user?.name : item.organization?.name}`, + }, + ]; const commonProps = { title: item.title, description: item.description, - metadataContent: [ - { - icon: Icons.calendar, - label: 'Date', - value: formatDate(item.modified), - }, - { - icon: Icons.download, - label: 'Download', - value: item.download_count.toString(), - }, - { - icon: Icons.globe, - label: 'Geography', - value: 'India', - }, - ], + metadataContent: MetadataContent, tag: item.tags, formats: item.formats, - footerContent: [ - { - icon: `/Sectors/${item.sectors[0]}.svg`, - label: 'Sectors', - }, - { icon: image, label: 'Published by' }, - ], + footerContent: FooterContent, }; return ( diff --git a/app/[locale]/(user)/components/PdfPreview.tsx b/app/[locale]/(user)/components/PdfPreview.tsx new file mode 100644 index 00000000..e28ae0c6 --- /dev/null +++ b/app/[locale]/(user)/components/PdfPreview.tsx @@ -0,0 +1,48 @@ +'use client'; + +import { useEffect, useState } from 'react'; + +interface PdfPreviewProps { + url: string; +} + +export default function PdfPreview({ url }: PdfPreviewProps) { + const [previewUrl, setPreviewUrl] = useState(null); + + useEffect(() => { + const fetchPdf = async () => { + try { + const response = await fetch(url); + const blobData = await response.blob(); + + // Manually set MIME type to PDF (in case it's sent as octet-stream) + const pdfBlob = new Blob([blobData], { type: 'application/pdf' }); + const objectUrl = URL.createObjectURL(pdfBlob); + setPreviewUrl(objectUrl); + } catch (error) { + console.error('Failed to load PDF:', error); + } + }; + + fetchPdf(); + + return () => { + if (previewUrl) { + URL.revokeObjectURL(previewUrl); + } + }; + }, [url]); + + if (!previewUrl) return

Loading PDF preview...

; + + return ( + +

PDF preview not available

+
+ ); +} diff --git a/app/[locale]/(user)/components/Sectors.tsx b/app/[locale]/(user)/components/Sectors.tsx index 193a7a06..45ef45cb 100644 --- a/app/[locale]/(user)/components/Sectors.tsx +++ b/app/[locale]/(user)/components/Sectors.tsx @@ -63,7 +63,7 @@ const Sectors = () => {
{data?.sectors.map((sectors: any) => (
diff --git a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Details/index.tsx b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Details/index.tsx index a5c24209..07e8213f 100644 --- a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Details/index.tsx +++ b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Details/index.tsx @@ -49,11 +49,7 @@ const DetailsQuery: any = graphql(` } `); -interface DetailsProps { - setShowcharts: (vars: boolean) => void; -} - -const Details: React.FC = ({ setShowcharts }) => { +const Details: React.FC = () => { const params = useParams(); const chartRef = useRef(null); @@ -62,12 +58,6 @@ const Details: React.FC = ({ setShowcharts }) => { () => GraphQL(DetailsQuery, {}, { datasetId: params.datasetIdentifier }) ); - useEffect(() => { - if (data && data?.getChartData.length <= 0) { - setShowcharts(false); - } - }, [data]); - const renderChart = (item: any) => { if (item.chartType === 'ASSAM_DISTRICT' || item.chartType === 'ASSAM_RC') { // Register the map @@ -84,13 +74,13 @@ const Details: React.FC = ({ setShowcharts }) => { const toggleDescription = () => setIsexpanded(!isexpanded); return ( -
+ <> {isLoading ? (
) : data?.getChartData?.length > 0 ? ( - <> +
@@ -98,21 +88,6 @@ const Details: React.FC = ({ setShowcharts }) => { {data?.getChartData.map((item: any, index: any) => (
-
- {item.__typename === 'TypeResourceChart' && - item?.chart?.options ? ( - renderChart(item) - ) : ( - {''} - )} - {/* Call the renderChart function */} -
{item.name} @@ -133,13 +108,6 @@ const Details: React.FC = ({ setShowcharts }) => {
- = ({ setShowcharts }) => {
+
+ {item.__typename === 'TypeResourceChart' && + item?.chart?.options ? ( + renderChart(item) + ) : ( + {''} + )} + {/* Call the renderChart function */} +
))} @@ -168,11 +152,11 @@ const Details: React.FC = ({ setShowcharts }) => {
- +
) : ( '' )} -
+ ); }; diff --git a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Metadata/index.tsx b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Metadata/index.tsx index 0a08167a..743ad154 100644 --- a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Metadata/index.tsx +++ b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Metadata/index.tsx @@ -1,9 +1,9 @@ import React, { useEffect, useState } from 'react'; import Image from 'next/image'; import Link from 'next/link'; -import { Button, Divider, Icon, Text } from 'opub-ui'; - -import { getWebsiteTitle } from '@/lib/utils'; +import { Button, Divider, Icon, Tag, Text, Tooltip } from 'opub-ui'; +import Styles from '../../../dataset.module.scss' +import { cn, formatDate, getWebsiteTitle } from '@/lib/utils'; import { Icons } from '@/components/icons'; interface MetadataProps { @@ -17,6 +17,7 @@ const MetadataComponent: React.FC = ({ data, setOpen }) => { value: item.value, type: item.metadataItem.dataType, })); + const [isexpanded, setIsexpanded] = useState(false); const toggleDescription = () => setIsexpanded(!isexpanded); @@ -78,7 +79,7 @@ const MetadataComponent: React.FC = ({ data, setOpen }) => { : '/org.png'; return ( -
+
= ({ data, setOpen }) => { {data.isIndividualDataset ? 'Publisher' : 'Organization'} - - {data.isIndividualDataset - ? data.user.fullName - : data.organization.name} - + + {data.isIndividualDataset + ? data.user.fullName + : data.organization.name} + +
Sector
- {data.sectors.length > 0 ? ( - data.sectors.map((sector: any, index: number) => ( - {sector.name - )) - ) : ( - N/A - )} + {data.sectors.length > 0 ? ( + data.sectors.map((sector: any, index: number) => ( + + {sector.name + + )) + ) : ( + N/A + )}
{Metadata.map((item: any, index: any) => ( -
+
{item.label} - {item.type !== 'URL' ? ( - - {item.value} - - ) : ( + {item.type === 'URL' ? ( - + {sourceTitle?.trim() ? sourceTitle : 'Visit Website'} + ) : item.type === 'DATE' ? ( + + {formatDate(item.value)} + + ) : item.type === 'MULTISELECT' ? ( +
+ {item.value.split(',').map((val: any, index: any) => ( + + {val.trim()} + + ))} +
+ ) : ( + + {item.value} + )}
))} @@ -189,9 +217,11 @@ const MetadataComponent: React.FC = ({ data, setOpen }) => {
)}
- Description - - {data.description?.length > 260 && !isexpanded + + Description + + + {/* {data.description?.length > 260 && !isexpanded ? `${data.description.slice(0, 260)}...` : data.description} {data.description?.length > 260 && ( @@ -203,7 +233,8 @@ const MetadataComponent: React.FC = ({ data, setOpen }) => { > {isexpanded ? 'See Less' : 'See More'} - )} + )} */} + {data.description}
diff --git a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/PrimaryData/index.tsx b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/PrimaryData/index.tsx index 7b332576..6b854cbc 100644 --- a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/PrimaryData/index.tsx +++ b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/PrimaryData/index.tsx @@ -18,15 +18,15 @@ const PrimaryData: React.FC = ({ data, isLoading }) => {
{data?.title} -
+
{data?.tags.map((item: any, index: any) => ( - {item.value}{' '} + {item.value} ))}
diff --git a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Resources/index.tsx b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Resources/index.tsx index 9657b9f7..1334762b 100644 --- a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Resources/index.tsx +++ b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/Resources/index.tsx @@ -2,6 +2,7 @@ import Link from 'next/link'; import { useParams } from 'next/navigation'; +import PdfPreview from '@/app/[locale]/(user)/components/PdfPreview'; import { graphql } from '@/gql'; import { useQuery } from '@tanstack/react-query'; import { @@ -88,6 +89,10 @@ const Resources = () => { accessorKey: 'name', header: 'Name of the Field', }, + { + accessorKey: 'description', + header: 'Description', + }, { accessorKey: 'format', header: 'Format', @@ -96,6 +101,7 @@ const Resources = () => { rows={row.original.schema.map((item: any) => ({ name: item.fieldName, format: item.format, + description: item.description, }))} /> @@ -156,15 +162,25 @@ const Resources = () => { - {previewData && ( - + {row.original.format === 'PDF' ? ( + + ) : ( + previewData && ( +
+ ) )} @@ -182,6 +198,7 @@ const Resources = () => { format: data?.fileDetails?.format || 'Na', size: Math.round(data?.fileDetails?.size / 1024).toFixed(2) + 'KB', preview: data?.previewData, + id: data?.id, }, ]; }; @@ -193,10 +210,10 @@ const Resources = () => { ) : getResourceDetails.data && getResourceDetails.data?.datasetResources?.length > 0 ? ( -
+
Files in this Dataset - + All files associated with this Dataset which can be downloaded{' '}
@@ -207,59 +224,64 @@ const Resources = () => { key={index} className="mt-5 flex flex-col gap-6 border-1 border-solid border-greyExtralight bg-surfaceDefault p-4 lg:mx-0 lg:p-6" > -
-
-
-
- {item.fileDetails?.format && ( - - )} - {item.name} -
-
- - -
- - - {' '} - View Details - - -
- - - +
+ + +
+
+ {item.fileDetails?.format && ( + + )} + + {item.name} + +
+
+ + + {' '} + View Details + + + + + +
-
- -
- - - - + +
+ + + ) @@ -274,3 +296,47 @@ const Resources = () => { }; export default Resources; + +{ + /* + +
+
+
(descriptionRefs.current[index] = el)} + className={!showMore[index] ? 'line-clamp-2' : ''} + > + {item.description} +
+ {isDescriptionLong[index] && ( + + )} +
+ + View Details + +
+ +
+ + + */ +} diff --git a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/SimilarDatasets/index.tsx b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/SimilarDatasets/index.tsx index 3093629f..df1056a8 100644 --- a/app/[locale]/(user)/datasets/[datasetIdentifier]/components/SimilarDatasets/index.tsx +++ b/app/[locale]/(user)/datasets/[datasetIdentifier]/components/SimilarDatasets/index.tsx @@ -75,11 +75,7 @@ const similarDatasetQuery: any = graphql(` } `); -interface Props { - showCharts: boolean; -} - -const SimilarDatasets: React.FC = ({ showCharts }) => { +const SimilarDatasets: React.FC = () => { const params = useParams(); const SimilatDatasetdetails: { data: any; isLoading: any } = useQuery( @@ -94,18 +90,15 @@ const SimilarDatasets: React.FC = ({ showCharts }) => { ) ); - return ( -
+
{SimilatDatasetdetails.isLoading ? (
) : ( <> -
+
Similar Datasets Similar Datasets that you may like
@@ -174,7 +167,6 @@ const SimilarDatasets: React.FC = ({ showCharts }) => {
- ; )}
diff --git a/app/[locale]/(user)/datasets/[datasetIdentifier]/page.tsx b/app/[locale]/(user)/datasets/[datasetIdentifier]/page.tsx index 3520cca7..cafdc0f3 100644 --- a/app/[locale]/(user)/datasets/[datasetIdentifier]/page.tsx +++ b/app/[locale]/(user)/datasets/[datasetIdentifier]/page.tsx @@ -69,8 +69,6 @@ const datasetQuery: any = graphql(` `); const DatasetDetailsPage = () => { - const [showCharts, setShowcharts] = useState(true); - const params = useParams(); const Datasetdetails: { data: any; isLoading: any } = useQuery( @@ -106,16 +104,9 @@ const DatasetDetailsPage = () => { isLoading={Datasetdetails.isLoading} /> )} -
- {showCharts ? ( -
- ) : ( - <> - - - - )} -
+
+ +
{Datasetdetails.isLoading ? ( @@ -131,14 +122,7 @@ const DatasetDetailsPage = () => { )}
- {showCharts && ( - <> -
- -
- - - )} + {/*
*/} diff --git a/app/[locale]/(user)/datasets/components/FIlter/Filter.tsx b/app/[locale]/(user)/datasets/components/FIlter/Filter.tsx index 240ee7f2..273b9d6e 100644 --- a/app/[locale]/(user)/datasets/components/FIlter/Filter.tsx +++ b/app/[locale]/(user)/datasets/components/FIlter/Filter.tsx @@ -47,7 +47,7 @@ const Filter: React.FC = ({ className=" font-medium text-secondaryText" onClick={handleReset} > - Reset + RESET diff --git a/app/[locale]/(user)/datasets/dataset.module.scss b/app/[locale]/(user)/datasets/dataset.module.scss index 6aa133bf..81b64ec8 100644 --- a/app/[locale]/(user)/datasets/dataset.module.scss +++ b/app/[locale]/(user)/datasets/dataset.module.scss @@ -3,10 +3,18 @@ width: 80%; height: 36px; } -/* In your global CSS/SCSS file */ - div[class*="Input-module_Backdrop"] { - border-top-color: var(--border-subdued) ; - border-radius: 8px; -} + /* In your global CSS/SCSS file */ + div[class*='Input-module_Backdrop'] { + border-top-color: var(--border-subdued); + border-radius: 8px; + } } +.Tag { + > span > span { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 120px; + } +} diff --git a/app/[locale]/(user)/publishers/PublisherCard.tsx b/app/[locale]/(user)/publishers/PublisherCard.tsx index 675231d1..5a9124d0 100644 --- a/app/[locale]/(user)/publishers/PublisherCard.tsx +++ b/app/[locale]/(user)/publishers/PublisherCard.tsx @@ -76,10 +76,14 @@ const PublisherCard: React.FC = ({ data }) => { : item?.description } > - + {item.__typename === 'TypeUser' - ? item.bio.slice(0, 100) + '...' - : item.description.slice(0, 100) + '...'} + ? item?.bio?.length > 220 + ? item.bio.slice(0, 220) + '...' + : item.bio + : item?.description?.length > 220 + ? item.description.slice(0, 220) + '...' + : item.description} diff --git a/app/[locale]/(user)/publishers/components/UseCases.tsx b/app/[locale]/(user)/publishers/components/UseCases.tsx index 2f5f33a1..be612051 100644 --- a/app/[locale]/(user)/publishers/components/UseCases.tsx +++ b/app/[locale]/(user)/publishers/components/UseCases.tsx @@ -60,6 +60,19 @@ const orgPublishedUseCasesDoc: any = graphql(` title summary slug + user { + fullName + profilePicture { + url + } + } + isIndividualUsecase + organization { + name + logo { + url + } + } metadata { metadataItem { id diff --git a/app/[locale]/(user)/publishers/page.tsx b/app/[locale]/(user)/publishers/page.tsx index 9e118dd9..5f9adad4 100644 --- a/app/[locale]/(user)/publishers/page.tsx +++ b/app/[locale]/(user)/publishers/page.tsx @@ -92,6 +92,7 @@ const PublishersListingPage = () => { variant="headingLg" color="onBgDefault" fontWeight="regular" + className=' leading-3 lg:leading-5' > Our Publishers are the backbone of our platform. Their contributions are what make up our platform. They belong to diff --git a/app/[locale]/(user)/sectors/page.tsx b/app/[locale]/(user)/sectors/page.tsx index d7c5bf5e..318f6ac9 100644 --- a/app/[locale]/(user)/sectors/page.tsx +++ b/app/[locale]/(user)/sectors/page.tsx @@ -88,6 +88,7 @@ const SectorsListingPage = () => { variant="headingLg" color="onBgDefault" fontWeight="regular" + className='leading-3 lg:leading-5' > We try to enable our users to create and participate in sectoral data collaboratives, amplifying the reach and @@ -124,57 +125,59 @@ const SectorsListingPage = () => { -
- - Explore Sectors - -
-
- { - setSearchText(e); - }} - onClear={() => { - setSearchText(''); - }} - name={'Start typing to search for any sector'} - /> -
- - Sort : - - { + handleSortChange(e); + }} + /> +
@@ -204,7 +207,7 @@ const SectorsListingPage = () => { {sectors.name} - +
{ + const params = useParams(); + const { data, isLoading } = useQuery<{ usecaseDashboards: any }>( + ['fetch_dashboardData', params.useCaseSlug], + () => GraphQL(DashboardsList, {}, { usecaseId: +params.useCaseSlug }), + { + refetchOnMount: true, + refetchOnReconnect: true, + } + ); + + return ( +
+ {isLoading ? ( + + ) : ( + data?.usecaseDashboards?.length > 0 && ( +
+
+ + Dashboards Linked to this Use Case + + + Analytical dashboards to explore the data further{' '} + +
+
+ {data?.usecaseDashboards?.map((dashboard: any) => ( + + + {dashboard.name} + + + ))} +
+
+ ) + )} +
+ ); +}; + +export default Dashboards; diff --git a/app/[locale]/(user)/usecases/[useCaseSlug]/page.tsx b/app/[locale]/(user)/usecases/[useCaseSlug]/page.tsx index f0fca2b5..5147d902 100644 --- a/app/[locale]/(user)/usecases/[useCaseSlug]/page.tsx +++ b/app/[locale]/(user)/usecases/[useCaseSlug]/page.tsx @@ -14,6 +14,7 @@ import { Icons } from '@/components/icons'; import { Loading } from '@/components/loading'; import PrimaryDetails from '../components/Details'; import Metadata from '../components/Metadata'; +import Dashboards from './Dashboards'; const UseCasedetails: any = graphql(` query UseCasedetails($pk: ID!) { @@ -21,6 +22,7 @@ const UseCasedetails: any = graphql(` id title summary + created isIndividualUsecase user { fullName @@ -62,6 +64,7 @@ const UseCasedetails: any = graphql(` url } } + platformUrl logo { name path @@ -188,12 +191,13 @@ const UseCaseDetailPage = () => {
- Datasets in this Use Case - + Datasets in this Use Case + All Datasets related to this Use Case
+ {/*
*/} {datasets.length > 0 && datasets.map((dataset: TypeDataset) => ( {
+ {(hasSupportingOrganizations || hasPartnerOrganizations || hasContributors) && ( @@ -252,7 +257,7 @@ const UseCaseDetailPage = () => {
{hasSupportingOrganizations && (
- + Supported by
@@ -277,7 +282,7 @@ const UseCaseDetailPage = () => { )} {hasPartnerOrganizations && (
- + Partnered by
@@ -303,11 +308,11 @@ const UseCaseDetailPage = () => {
{hasContributors && (
-
- +
+ Contributors{' '} - + Publisher and Contributors who have added to the Use Case
diff --git a/app/[locale]/(user)/usecases/components/Details.tsx b/app/[locale]/(user)/usecases/components/Details.tsx index 8ed2b916..a034a570 100644 --- a/app/[locale]/(user)/usecases/components/Details.tsx +++ b/app/[locale]/(user)/usecases/components/Details.tsx @@ -18,7 +18,13 @@ const PrimaryDetails = ({ data, isLoading }: { data: any; isLoading: any }) => {
{data.useCase.tags.map((item: any, index: number) => (
- {item.value} + + {item.value} +
))}
@@ -63,11 +69,15 @@ const PrimaryDetails = ({ data, isLoading }: { data: any; isLoading: any }) => { className="h-full w-full" />
-
+
- GEOGRAPHIES + GEOGRAPHIES
- + { data.useCase.metadata?.find( (meta: any) => meta.metadataItem?.label === 'Geography' @@ -77,9 +87,9 @@ const PrimaryDetails = ({ data, isLoading }: { data: any; isLoading: any }) => {
- Summary + Summary
- + {data.useCase.summary}
diff --git a/app/[locale]/(user)/usecases/components/Metadata.tsx b/app/[locale]/(user)/usecases/components/Metadata.tsx index 502ab8de..4326ee99 100644 --- a/app/[locale]/(user)/usecases/components/Metadata.tsx +++ b/app/[locale]/(user)/usecases/components/Metadata.tsx @@ -1,17 +1,43 @@ +import { useEffect, useState } from 'react'; import Image from 'next/image'; import Link from 'next/link'; -import { Button, Divider, Icon, Text } from 'opub-ui'; +import { Button, Divider, Icon, Text, Tooltip } from 'opub-ui'; -import { formatDate } from '@/lib/utils'; +import { formatDate, getWebsiteTitle } from '@/lib/utils'; import { Icons } from '@/components/icons'; const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { + const [platformTitle, setPlatformTitle] = useState(null); + + useEffect(() => { + const fetchTitle = async () => { + try { + const urlItem = data.useCase.platformUrl; + + if (urlItem && urlItem.value) { + const title = await getWebsiteTitle(urlItem.value); + setPlatformTitle(title); + } + } catch (error) { + console.error('Error fetching website title:', error); + } + }; + + if (data.useCase.platformUrl === null) { + setPlatformTitle('N/A'); + } else { + fetchTitle(); + } + }, [data.useCase.platformUrl]); const metadata = [ { label: data.useCase.isIndividualUsecase ? 'Publisher' : 'Organization', value: data.useCase.isIndividualUsecase ? data.useCase.user.fullName : data?.useCase.organization?.name, + tooltipContent: data.useCase.isIndividualUsecase + ? data.useCase.user.fullName + : data?.useCase.organization?.name, }, { label: 'Contact', @@ -24,18 +50,39 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { {data.useCase.isIndividualUsecase ? 'Publisher' : 'Organization'} ), + + }, + { + label: 'Platform URL', + value: + data.useCase.platformUrl === null ? ( + 'N/A' + ) : ( + + + {platformTitle?.trim() ? platformTitle : 'Visit Platform'} + + + ), + tooltipContent: data.useCase.platformUrl === null ? 'N/A' : platformTitle, }, { label: 'Started On', value: formatDate(data.useCase.created) || 'N/A', + tooltipContent: formatDate(data.useCase.created) || 'N/A', }, { label: 'Status', value: data.useCase.runningStatus.split('_').join('') || 'N/A', + tooltipContent: data.useCase.runningStatus.split('_').join('') || 'N/A', }, { label: 'Last Updated', value: formatDate(data.useCase.modified) || 'N/A', + tooltipContent: formatDate(data.useCase.modified) || 'N/A', }, { label: 'Sectors', @@ -43,14 +90,15 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => {
{data.useCase.sectors.length > 0 ? ( data.useCase.sectors.map((sector: any, index: number) => ( - + + + )) ) : ( N/A // Fallback if no sectors are available @@ -67,14 +115,15 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { ?.find((meta: any) => meta.metadataItem?.label === 'SDG Goal') ?.value.split(', ') .map((item: any, index: number) => ( - + + + )) ) : ( N/A @@ -100,9 +149,9 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { fontWeight="semibold" className=" text-primaryBlue" > - ABOUT THE USECASE{' '} + ABOUT THE USE CASE{' '} - METADATA + DETAILS
{setOpen && ( @@ -136,13 +185,16 @@ const Metadata = ({ data, setOpen }: { data: any; setOpen?: any }) => { > {item.label} - - {typeof item.value === 'string' ? item.value : item.value} - + + + {typeof item.value === 'string' ? item.value : item.value} + +
))}
diff --git a/app/[locale]/(user)/usecases/page.tsx b/app/[locale]/(user)/usecases/page.tsx index 6d7bf1b8..c8dce012 100644 --- a/app/[locale]/(user)/usecases/page.tsx +++ b/app/[locale]/(user)/usecases/page.tsx @@ -90,13 +90,13 @@ const UseCasesListingPage = () => {
- + Our Use Cases By Use case we mean any specific sector or domain data led interventions that can be applied to address some of the most @@ -113,9 +113,9 @@ const UseCasesListingPage = () => { />
-
+
- Explore Use Cases + Explore Use Cases
{getUseCasesList.isLoading ? (
@@ -124,7 +124,7 @@ const UseCasesListingPage = () => { ) : (
diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/admin/addUser.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/admin/addUser.tsx index 854fb21e..7cc4f207 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/admin/addUser.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/admin/addUser.tsx @@ -17,15 +17,18 @@ import { FetchUsers } from '../usecases/edit/[id]/contributors/query'; const addUserDoc: any = graphql(` mutation addUserToOrganization($input: AddRemoveUserToOrganizationInput!) { addUserToOrganization(input: $input) { - __typename - ... on TypeOrganizationMembershipMutationResponse { - data { - role { - name - id - } + success + errors { + nonFieldErrors + fieldErrors { + messages + } + } + data { + role { + name + id } - success } } } @@ -74,7 +77,9 @@ const AddUser = ({ () => GraphQL( FetchUsers, - {}, + { + [params.entityType]: params.entitySlug, + }, { limit: 10, searchTerm: searchValue, @@ -121,18 +126,24 @@ const AddUser = ({ input ), { - onSuccess: (res: any) => { - toast('User added successfully'); - // Optionally, reset form or perform other actions - setIsOpen(false); - setFormData({ - userId: '', - roleId: '', - }); - setRefetch(true); - }, - onError: (err: any) => { - toast('Failed to add user'); + onSuccess: (data: any) => { + if (data.addUserToOrganization.success) { + toast('User added successfully'); + setIsOpen(false); + setFormData({ + userId: '', + roleId: '', + }); + setRefetch(true); + } else { + toast( + 'Error: ' + + (data.addUserToOrganization?.errors?.fieldErrors + ? data.addUserToOrganization?.errors?.fieldErrors[0] + ?.messages[0] + : data.addUserToOrganization?.errors?.nonFieldErrors[0]) + ); + } }, } ); @@ -149,7 +160,6 @@ const AddUser = ({ { onSuccess: (res: any) => { toast('User updated successfully'); - // Optionally, reset form or perform other actions setIsOpen(false); setFormData({ userId: '', diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/admin/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/admin/page.tsx index afe31bb0..1bb5e3ee 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/admin/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/admin/page.tsx @@ -45,14 +45,19 @@ const Admin = () => { const params = useParams<{ entityType: string; entitySlug: string }>(); const usersList: { data: any; isLoading: boolean; refetch: any } = useQuery( [`fetch_users_list_admin_members`], - () => GraphQL(usersListDoc, { - [params.entityType]: params.entitySlug, - }, []) + () => + GraphQL( + usersListDoc, + { + [params.entityType]: params.entitySlug, + }, + [] + ) ); const [isOpen, setIsOpen] = useState(false); const [isEdit, setIsEdit] = useState(false); const [selectedUser, setSelectedUser] = useState({}); - const [refetch,setRefetch]=useState(false) + const [refetch, setRefetch] = useState(false); const { mutate, isLoading: removeUserLoading } = useMutation( (input: { input: AddRemoveUserToOrganizationInput }) => @@ -140,7 +145,20 @@ const Admin = () => { id: item.id, })) || [], }; - + + useEffect(() => { + const updatedRows = + usersList.data?.userByOrganization.map((item: any) => ({ + name: item.fullName, + role: item.organizationMemberships[0]?.role?.name || 'N/A', + roleId: item.organizationMemberships[0]?.role?.id || '', + modified: + formatDate(item.organizationMemberships[0]?.updatedAt) || 'N/A', + id: item.id, + })) || []; + + setFilteredRows(updatedRows); + }, [usersList.data]); const [filteredRows, setFilteredRows] = React.useState(table.rows); const handleSearchChange = (e: string) => { @@ -151,6 +169,10 @@ const Admin = () => { setFilteredRows(filtered); }; + const filteredColumns = table.columns.filter( + (column) => column.accessorKey !== 'id' + ); + useEffect(() => { usersList.refetch(); setRefetch(false); @@ -201,13 +223,13 @@ const Admin = () => {
{usersList.data?.userByOrganization?.length > 0 ? ( ) : ( - + )}
diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/charts/components/ChartsImage.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/charts/components/ChartsImage.tsx index 6ca33f25..fcfe63b1 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/charts/components/ChartsImage.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/charts/components/ChartsImage.tsx @@ -183,7 +183,9 @@ const ChartsImage: React.FC = ({ const { mutate, isLoading: editMutationLoading } = useMutation( (data: { data: ResourceChartImageInputPartial }) => - GraphQL(UpdateChartImageMutation, {}, data), + GraphQL(UpdateChartImageMutation, { + [params.entityType]: params.entitySlug, + }, data), { onSuccess: () => { toast('ChartImage updated successfully'); diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/components/title-bar.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/components/title-bar.tsx index a58ac924..0989e81b 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/components/title-bar.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/components/title-bar.tsx @@ -1,6 +1,6 @@ +import { useEffect, useState } from 'react'; import Link from 'next/link'; import { Button, Icon, Spinner, Text, TextField } from 'opub-ui'; -import { useEffect, useState } from 'react'; import { Icons } from '@/components/icons'; @@ -11,7 +11,8 @@ interface TitleBarProps { onSave: (data: any) => void; loading: boolean; status: 'loading' | 'success'; - setStatus: (s: 'loading' | 'success') => void;} + setStatus: (s: 'loading' | 'success') => void; +} const TitleBar = ({ label, @@ -43,7 +44,9 @@ const TitleBar = ({ }} /> ) : ( - {title} + + {title} + )}
{edit && ( diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/components/EditDistribution.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/components/EditDistribution.tsx deleted file mode 100644 index 58ea0a73..00000000 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/components/EditDistribution.tsx +++ /dev/null @@ -1,263 +0,0 @@ -import React from 'react'; -import { graphql } from '@/gql'; -// import { FileInputType, ResourceInput } from '@/gql/generated/graphql'; -import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { - Button, - Divider, - DropZone, - FormLayout, - Icon, - Input, - Select, - Text, -} from 'opub-ui'; - -import { GraphQL } from '@/lib/api'; -import { bytesToSize } from '@/lib/utils'; -import { Icons } from '@/components/icons'; -import { DatasetForm } from '../../../components/dataset-form'; - -// const createResourceMutationDoc: any = graphql(` -// mutation createResourceMutation($resource_data: ResourceInput) { -// create_resource(resource_data: $resource_data) { -// success -// errors -// resource { -// id -// title -// description -// file_details { -// resource { -// id -// title -// description -// } -// format -// file -// remote_url -// source_file_name -// } -// } -// } -// } -// `); - -interface Props { - id: string; - defaultVal: { - id: string; - resources: { - title: string; - description: string; - file_details?: any; - }[]; - }; - submitRef: React.RefObject; - setPage: (page: 'list' | 'create') => void; -} - -export function EditDistribution({ - id, - defaultVal, - submitRef, - setPage, -}: Props) { - // const [val, setVal] = React.useState(defaultVal); - const [fileSelected, setFileSelected] = React.useState(false); - - const queryClient = useQueryClient(); - // const { mutate, isLoading } = useMutation( - // (data: { resource_data: ResourceInput }) => - // GraphQL(createResourceMutationDoc, data), - // { - // onSuccess: () => { - // queryClient.invalidateQueries({ - // queryKey: [`dataset_distribution_${id}`], - // }); - // }, - // } - // ); - - return ( - <> - { - // mutate({ - // resource_data: { - // dataset: defaultVal.id, - // status: 'DRAFT', - // title: data.title, - // description: data.description, - // file_details: { - // file: data.file_details[0], - // }, - // }, - // }); - }} - formOptions={{ defaultValues: defaultVal }} - submitRef={submitRef} - // onChange={setVal} - > - <>Test - {/* <> - Add Distribution -
- -
- -
- - - } - error="This field is required" - readOnly={isLoading} - disabled={fileSelected} - /> - - - - - - -
-
- -
-
- -
- - -
-
- */} -
- - ); -} - -const FileUpload = ({ - required, - error, - disabled, - setFileSelected, -}: { - required?: boolean; - error?: string; - disabled?: boolean; - setFileSelected: (val: boolean) => void; -}) => { - const [file, setFile] = React.useState(); - - const handleDropZoneDrop = React.useCallback( - (_dropFiles: File[], acceptedFiles: File[]) => { - setFile(acceptedFiles[0]); - setFileSelected(true); - }, - [setFileSelected] - ); - - function handleFileDelete(props: React.MouseEvent) { - props.stopPropagation(); - setFileSelected(false); - setFile(undefined); - } - - const hint = ( - - Supported file type: .pdf, .csv, .xls
- The file size should not be more than 5 MB -
- ); - - const fileUpload = !file && ; - const uploadedFile = file && ( -
-
- - -
-
- - {file.name} - -
- - {bytesToSize(file.size)} - -
-
-
- ); - - return ( - - {uploadedFile} - {fileUpload} - - ); -}; diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/components/EditMetadata.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/components/EditMetadata.tsx index 10639f6a..a1231a8e 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/components/EditMetadata.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/components/EditMetadata.tsx @@ -102,6 +102,7 @@ const updateMetadataMutationDoc: any = graphql(` field messages } + nonFieldErrors } data { id @@ -172,16 +173,19 @@ export function EditMetadata({ id }: { id: string }) { ) ); - const getTagsList: { data: any; isLoading: boolean; error: any } = useQuery( - [`tags_list_query`], - () => - GraphQL( - tagsListQueryDoc, - { - [params.entityType]: params.entitySlug, - }, - [] - ) + const getTagsList: { + data: any; + isLoading: boolean; + error: any; + refetch: any; + } = useQuery([`tags_list_query`], () => + GraphQL( + tagsListQueryDoc, + { + [params.entityType]: params.entitySlug, + }, + [] + ) ); const getMetaDataListQuery: { @@ -203,6 +207,8 @@ export function EditMetadata({ id }: { id: string }) { ) ); + const [isTagsListUpdated, setIsTagsListUpdated] = useState(false); + const updateMetadataMutation = useMutation( (data: { UpdateMetadataInput: UpdateMetadataInput }) => GraphQL( @@ -225,13 +231,19 @@ export function EditMetadata({ id }: { id: string }) { const updatedData = defaultValuesPrepFn( res.addUpdateDatasetMetadata.data ); + if (isTagsListUpdated) { + getTagsList.refetch(); + setIsTagsListUpdated(false); + } setFormData(updatedData); setPreviousFormData(updatedData); - // getDatasetMetadata.refetch(); } else { - toast( + toast( 'Error: ' + - res.addUpdateDatasetMetadata.errors.fieldErrors[0].messages[0] + (res.addUpdateDatasetMetadata?.errors?.fieldErrors + ? res.addUpdateDatasetMetadata?.errors?.fieldErrors[0] + ?.messages[0] + : res.addUpdateDatasetMetadata?.errors?.nonFieldErrors[0]) ); } }, @@ -316,7 +328,9 @@ export function EditMetadata({ id }: { id: string }) { const transformedValues = Object.keys(updatedData)?.reduce( (acc: any, key) => { acc[key] = Array.isArray(updatedData[key]) - ? updatedData[key].map((item: any) => item.value || item).join(', ') + ? updatedData[key] + .map((item: any) => item?.value || item) + .join(', ') : updatedData[key]; return acc; }, @@ -531,17 +545,17 @@ export function EditMetadata({ id }: { id: string }) { { - return { - label: item.value, - value: item.id, - }; - })} + list={getTagsList.data?.tags?.map((item: TypeTag) => ({ + label: item.value, + value: item.id, + }))} + key={`tags-${getTagsList.data?.tags?.length}`} // forces remount on change label="Tags *" creatable onChange={(value) => { + setIsTagsListUpdated(true); handleChange('tags', value); - handleSave({ ...formData, tags: value }); // Save on change + handleSave({ ...formData, tags: value }); }} />
@@ -582,9 +596,11 @@ export function EditMetadata({ id }: { id: string }) { defaultChecked={false} disabled > -
- Restricted Access - +
+ + Restricted Access + + Users would require to request access to the dataset to view and download it. Recommended for sensitive data. diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/publish/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/publish/page.tsx index 1635c064..83d8c317 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/publish/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/publish/page.tsx @@ -130,6 +130,10 @@ const generateColumnData = (name: any) => { accessorKey: 'name', header: 'Name of the Field', }, + { + accessorKey: 'description', + header: 'Description', + }, { accessorKey: 'format', header: 'Format', @@ -137,6 +141,7 @@ const generateColumnData = (name: any) => { ]} rows={row.original.dialog.map((item: any) => ({ name: item.fieldName, + description: item.description, format: item.format, }))} hideFooter diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/EditResource.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/EditResource.tsx index 686dcdca..856f6672 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/EditResource.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/EditResource.tsx @@ -13,22 +13,19 @@ import { Checkbox, Divider, DropZone, - Icon, - Spinner, Text, TextField, toast, } from 'opub-ui'; import { GraphQL } from '@/lib/api'; -import { Icons } from '@/components/icons'; import { Loading } from '@/components/loading'; +import PdfPreview from '../../../../../../../../(user)/components/PdfPreview'; import { useDatasetEditStatus } from '../../context'; import { TListItem } from '../page-layout'; import PreviewData from './PreviewData'; import { createResourceFilesDoc, - resetSchema, updateResourceDoc, updateSchema, } from './query'; @@ -72,6 +69,7 @@ const resourceDetails: any = graphql(` resource { pk } + format file { name path @@ -86,10 +84,14 @@ const resourceDetails: any = graphql(` `); export const EditResource = ({ refetch, allResources }: EditProps) => { - const params = useParams(); + const params = useParams<{ + entityType: string; + entitySlug: string; + id: string; + }>(); const [resourceId, setResourceId] = useQueryState('id', parseAsString); - const [schema, setSchema] = React.useState([]); + const [schema, setSchema] = React.useState([]); const resourceDetailsQuery = useQuery( [`fetch_resource_details_${resourceId}`], @@ -97,7 +99,7 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { GraphQL( resourceDetails, { - // Entity Headers if present + [params.entityType]: params.entitySlug, }, { resourceId: resourceId } ), @@ -105,25 +107,7 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { enabled: !!resourceId, } ); - const schemaMutation = useMutation( - (data: { resourceId: string }) => - GraphQL( - resetSchema, - { - // Entity Headers if present - }, - data - ), - { - onSuccess: (data: any) => { - setSchema(data.resetFileResourceSchema.schema); - refetch(); - }, - onError: (err: any) => { - toast(err); - }, - } - ); + const updateResourceMutation = useMutation( (data: { fileResourceInput: UpdateFileResourceInput; @@ -132,7 +116,7 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { GraphQL( updateResourceDoc, { - // Entity Headers if present + [params.entityType]: params.entitySlug, }, data ), @@ -144,11 +128,7 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { onClick: () => {}, }, }); - if (variables.isResetSchema) { - schemaMutation.mutate({ - resourceId: resourceId, - }); - } + resourceDetailsQuery.refetch(); }, onError: (err: any) => { @@ -163,7 +143,7 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { GraphQL( updateSchema, { - // Entity Headers if present + [params.entityType]: params.entitySlug, }, data ), @@ -187,7 +167,7 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { GraphQL( createResourceFilesDoc, { - // Entity Headers if present + [params.entityType]: params.entitySlug, }, data ), @@ -233,9 +213,9 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { columns: [], }); - useEffect(() => { - resourceDetailsQuery.refetch(); - }, []); + // useEffect(() => { + // resourceDetailsQuery.refetch(); + // }, []); React.useEffect(() => { const ResourceData = resourceDetailsQuery.data?.resourceById; @@ -250,13 +230,16 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { rows: ResourceData?.previewData?.rows, columns: ResourceData?.previewData?.columns, }); - setSchema(ResourceData?.schema); - if (ResourceData?.schema?.length === 0) { - schemaMutation.mutate({ - resourceId: resourceId, - }); + }, [resourceDetailsQuery.data]); + + + useEffect(() => { + const schemaData = resourceDetailsQuery.data?.resourceById?.schema; + if (schemaData && Array.isArray(schemaData)) { + setSchema(schemaData); } }, [resourceDetailsQuery.data]); + const handleResourceChange = (e: any) => { setResourceId(e, { shallow: false }); @@ -300,16 +283,7 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { { onSuccess: () => { // Automatically trigger schema mutation after file upload - schemaMutation.mutate( - { - resourceId: resourceId, - }, - { - onSuccess: () => { - toast('Schema updated successfully'); - }, - } - ); + resourceDetailsQuery.refetch(); }, } @@ -377,6 +351,9 @@ export const EditResource = ({ refetch, allResources }: EditProps) => { ); // update based on mutation state }, [updateResourceMutation.isLoading, updateSchemaMutation.isLoading]); + const resourceFormat = + resourceDetailsQuery.data?.resourceById.fileDetails.format?.toLowerCase(); + const pdfUrl = `${process.env.NEXT_PUBLIC_BACKEND_URL}/api/download/resource/${resourceId}`; return (
{resourceDetailsQuery.data?.resourceById ? ( @@ -446,42 +423,49 @@ export const EditResource = ({ refetch, allResources }: EditProps) => {
-
- { - const newValue = !previewEnable; - setPreviewEnable(newValue); - updateResourceMutation.mutate({ - fileResourceInput: { - id: resourceId, - name: resourceName || '', - previewEnabled: newValue, // use new value here - previewDetails: { - startEntry: 1, - endEntry: 5, - isAllEntries: previewDetails.isAllEntries, + {resourceFormat !== 'zip' && ( +
+ { + const newValue = !previewEnable; + setPreviewEnable(newValue); + updateResourceMutation.mutate({ + fileResourceInput: { + id: resourceId, + name: resourceName || '', + previewEnabled: newValue, // use new value here + previewDetails: { + startEntry: 1, + endEntry: 5, + isAllEntries: previewDetails.isAllEntries, + }, }, - }, - isResetSchema: false, - }); - }} - > - Preview Enabled - -
- -
- {/* {previewEnable && ( + Preview Enabled + +
+ +
+ {/* {previewEnable && ( <> { )} )} */} -
- {showPreview && previewEnable && previewData && ( - - )} -
-
- Fields in the Resource -
- - The Field settings apply to the Resource on a master level and can - not be changed in Access Models. - - {schemaMutation.isLoading ? ( -
- -
- ) : resourceId && schema?.length > 0 ? ( + )} + {showPreview && + previewEnable && + (resourceFormat === 'pdf' ? ( + + ) : ( + previewData && + ))} + + {resourceFormat !== 'pdf' && resourceFormat !== 'zip' && ( +
+ {/*
+ Fields in the Resource + +
*/} + + The Field settings apply to the Resource on a master level and + can not be changed in Access Models. + + - ) : ( -
- {' '} - Click on Reset Format{' '} -
- )} -
+
+ )}
) : ( diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/PreviewData.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/PreviewData.tsx index ba4c9856..5e0e7ebb 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/PreviewData.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/PreviewData.tsx @@ -1,14 +1,13 @@ import { DataTable } from 'opub-ui'; interface EditProps { - isPreview: boolean; previewData: { columns: string[]; rows: any[]; }; } -const PreviewData = ({ isPreview, previewData }: EditProps) => { +const PreviewData = ({ previewData }: EditProps) => { const previewColumns = previewData?.columns?.map((column: string) => ({ accessorKey: column, @@ -16,6 +15,7 @@ const PreviewData = ({ isPreview, previewData }: EditProps) => { cell: ({ cell }: any) => { const value = cell.getValue(); return {value !== null ? value?.toString() : 'N/A'}; + ``; }, })) || []; @@ -29,14 +29,12 @@ const PreviewData = ({ isPreview, previewData }: EditProps) => { return rowData; }) || []; return ( -
- -
+ ); }; diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceDropzone.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceDropzone.tsx index 8cb0bee4..84af7726 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceDropzone.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceDropzone.tsx @@ -1,15 +1,15 @@ +import React from 'react'; +import { useParams } from 'next/navigation'; import { CreateFileResourceInput } from '@/gql/generated/graphql'; import { useMutation } from '@tanstack/react-query'; import { parseAsString, useQueryState } from 'next-usequerystate'; -import { useParams } from 'next/navigation'; -import { Button, DropZone, Text, toast } from 'opub-ui'; -import React from 'react'; +import { Button, DropZone, Tag, Text, toast } from 'opub-ui'; import { GraphQL } from '@/lib/api'; import { createResourceFilesDoc } from './query'; export const ResourceDropzone = ({ reload }: { reload: () => void }) => { - const fileTypes = ['PDF', 'CSV', 'XLS', 'XLSX', 'TXT', 'ZIP']; + const fileTypes = ['CSV', 'JSON', 'PDF', 'XLS', 'XLSX', 'XML', 'ZIP']; const params = useParams<{ entityType: string; entitySlug: string; @@ -58,17 +58,21 @@ export const ResourceDropzone = ({ reload }: { reload: () => void }) => { - Maximum File Size Limit : 5 MB - - Supported File Types :{' '} - {fileTypes.map((type, index) => { - return ( -
- {type} -
- ); - })} -
+ Maximum File Size Limit : 25 MB +
+ + Supported File Types: + +
+ {fileTypes.map((type, index) => { + return ( + + {type} + + ); + })} +
+
); @@ -79,7 +83,7 @@ export const ResourceDropzone = ({ reload }: { reload: () => void }) => { return ( <> void; isSheetOpen: boolean; setIsSheetOpen: (open: boolean) => void; - dropZone:any; + dropZone: any; uploadedFile: React.ReactNode; file: File[]; list: { value: string; label: string }[]; @@ -25,7 +25,7 @@ const ResourceHeader = ({ list, resourceId, handleResourceChange, -}:ResourceHeaderProps) => { +}: ResourceHeaderProps) => { return (
@@ -59,11 +59,16 @@ const ResourceHeader = ({ {uploadedFile} - {file.length === 0 && } + {file.length === 0 && ( + + )} diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceListView.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceListView.tsx index b79dab3d..c9d1f1dd 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceListView.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceListView.tsx @@ -247,6 +247,7 @@ export const ResourceListView = ({ data, refetch }: ResourceListProps) => { label="Search" name="Search" onChange={(e) => handleSearchChange(e)} + onClear={() => handleSearchChange('')} />
@@ -258,12 +259,17 @@ export const ResourceListView = ({ data, refetch }: ResourceListProps) => { ) : ( {uploadedFile} - {file.length === 0 && } + {file.length === 0 && ( + + )} )} diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceSchema.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceSchema.tsx index 55aad4f4..62743e49 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceSchema.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/dataset/[id]/edit/resources/components/ResourceSchema.tsx @@ -53,7 +53,7 @@ export const ResourceSchema = ({ ...newData[rowIndex], [field]: newValue, }; - + setUpdatedData(newData); setSchema(newData); handleSave(newData); @@ -109,29 +109,15 @@ export const ResourceSchema = ({ { accessorKey: 'format', header: 'FORMAT', - cell: (info: any) => { - const rowIndex = info.row.index; - const format = updatedData[rowIndex]?.format || ''; - return ( - { }} />
+
+ + +
+
+ { + handleChange('startedOn', e); + }} + onBlur={() => handleSave(formData)} + /> +
+
{ max={new Date().toISOString().split('T')[0]} min={formData.startedOn || ''} disabled={ - formData.runningStatus === 'COMPLETED' || - formData.runningStatus === 'CANCELLED' + formData.runningStatus === 'ON_GOING' || + formData.runningStatus === 'INITIATED' } value={formData.completedOn || ''} onChange={(e) => { diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/metadata/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/metadata/page.tsx index c559de5b..7c0bfc0f 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/metadata/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/metadata/page.tsx @@ -115,7 +115,14 @@ const Metadata = () => { const useCaseData: { data: any; isLoading: boolean } = useQuery( [`fetch_UseCaseData_Metadata`], - () => GraphQL(FetchUseCasedetails, {}, { filters: { id: params.id } }), + () => + GraphQL( + FetchUseCasedetails, + { + [params.entityType]: params.entitySlug, + }, + { filters: { id: params.id } } + ), { refetchOnMount: true, refetchOnReconnect: true, @@ -201,25 +208,36 @@ const Metadata = () => { ) ); - const getTagsList: { data: any; isLoading: boolean; error: any } = useQuery( - [`tags_list_query`], - () => - GraphQL( - tagsListQueryDoc, - { - [params.entityType]: params.entitySlug, - }, - [] - ) + const getTagsList: { + data: any; + isLoading: boolean; + error: any; + refetch: any; + } = useQuery([`tags_list_query`], () => + GraphQL( + tagsListQueryDoc, + { + [params.entityType]: params.entitySlug, + }, + [] + ) ); + const [isTagsListUpdated, setIsTagsListUpdated] = useState(false); + // Update mutation const updateUseCase = useMutation( (data: { updateMetadataInput: UpdateUseCaseMetadataInput }) => - GraphQL(UpdateUseCaseMetadataMutation, {}, data), + GraphQL(UpdateUseCaseMetadataMutation, { + [params.entityType]: params.entitySlug, + }, data), { onSuccess: (res: any) => { toast('Use case updated successfully'); const updatedData = defaultValuesPrepFn(res.addUpdateUsecaseMetadata); + if (isTagsListUpdated) { + getTagsList.refetch(); + setIsTagsListUpdated(false); + } setFormData(updatedData); setPreviousFormData(updatedData); }, @@ -259,7 +277,11 @@ const Metadata = () => { id: params.id, metadata: [ ...Object.keys(transformedValues) - .filter((valueItem) => !['sectors', 'tags'].includes(valueItem)) + .filter( + (valueItem) => + !['sectors', 'tags'].includes(valueItem) && + transformedValues[valueItem] !== '' + ) .map((key) => { return { id: key, @@ -319,7 +341,7 @@ const Metadata = () => { value: option, })) || []), ]} - label={metadataFormItem.label+ ' *'} + label={metadataFormItem.label + ' *'} selectedValue={formData[metadataFormItem.id]} displaySelected onChange={(value) => { @@ -348,8 +370,10 @@ const Metadata = () => { value: item.id, })) || [] } + key={`tags-${getTagsList.data?.tags?.length}`} // forces remount on change selectedValue={formData.tags} onChange={(value) => { + setIsTagsListUpdated(true); handleChange('tags', value); handleSave({ ...formData, tags: value }); }} diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Assign.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Assign.tsx new file mode 100644 index 00000000..2866668f --- /dev/null +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Assign.tsx @@ -0,0 +1,32 @@ +import { Table } from 'opub-ui'; + +import { formatDate } from '@/lib/utils'; + +const Assign = ({ data }: { data: any }) => { + const columns = [ + { accessorKey: 'title', header: 'Title' }, + { accessorKey: 'sector', header: 'Sector' }, + { accessorKey: 'modified', header: 'Last Modified' }, + ]; + + const generateTableData = (list: Array) => { + return list?.map((item) => { + return { + title: item.title, + id: item.id, + sector: item.sectors[0]?.name, + modified: formatDate(item.modified), + }; + }); + }; + return ( +
+
+ + ); +}; +export default Assign; diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Contributors.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Contributors.tsx new file mode 100644 index 00000000..8fced4f5 --- /dev/null +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Contributors.tsx @@ -0,0 +1,109 @@ +import Image from 'next/image'; +import { Text } from 'opub-ui'; + +const Contributors = ({ data }: { data: any }) => { + const ContributorDetails = [ + { + label: 'Contributors', + value: + data?.useCases[0]?.contributors.length > 0 + ? data?.useCases[0]?.contributors + .map((item: any) => item.fullName) + .join(', ') + : 'No Contributors', + image: data?.useCases[0]?.contributors, + }, + ]; + + const OrgDetails = [ + { + label: 'Supporters', + value: + data?.useCases[0]?.supportingOrganizations.length > 0 + ? data?.useCases[0]?.supportingOrganizations + .map((item: any) => item.name) + .join(', ') + : 'No Supporting Organizations', + image: data?.useCases[0]?.supportingOrganizations, + }, + { + label: 'Partners', + value: + data?.useCases[0]?.partnerOrganizations.length > 0 + ? data?.useCases[0]?.partnerOrganizations + .map((item: any) => item.name) + .join(', ') + : 'No Partner Organizations', + image: data?.useCases[0]?.partnerOrganizations, + }, + ]; + return ( +
+ {ContributorDetails.map((item: any, index: number) => ( +
+
+ {item.label}: +
+
+ {item?.image.map((data: any, index: number) => ( +
+ + + + {data.fullName} + +
+ ))} +
+
+ ))} + {OrgDetails.map((item: any, index: number) => ( +
+
+ {item.label}: +
+
+ {item.image.map((data: any, index: number) => ( +
+
+ +
+ + {data.name} + +
+ ))} +
+
+ ))} +
+ ); +}; + +export default Contributors; \ No newline at end of file diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Dashboards.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Dashboards.tsx new file mode 100644 index 00000000..56e3457e --- /dev/null +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Dashboards.tsx @@ -0,0 +1,31 @@ +import { Table, Text } from 'opub-ui'; + +const Dashboards = ({ data }: { data: any }) => { + const dashboardColumns = [ + { accessorKey: 'name', header: 'Name' }, + { accessorKey: 'link', header: 'Link' }, + ]; + + const generatePublisherData = (list: Array) => { + return list?.map((item) => { + return { + name: item.name, + link: item.link, + }; + }); + }; + return ( +
+ {data?.length > 0 ? ( +
+ ) : ( + No Dashboards Found + )} + + ); +}; +export default Dashboards; diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Details.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Details.tsx new file mode 100644 index 00000000..ac096633 --- /dev/null +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/Details.tsx @@ -0,0 +1,106 @@ +import { useEffect, useState } from 'react'; +import Image from 'next/image'; +import Link from 'next/link'; +import { Text } from 'opub-ui'; + +import { getWebsiteTitle } from '@/lib/utils'; + +const Details = ({ data }: { data: any }) => { + const [platformTitle, setPlatformTitle] = useState(null); + + useEffect(() => { + const fetchTitle = async () => { + try { + const urlItem = data.useCases[0].platformUrl; + + if (urlItem && urlItem.value) { + const title = await getWebsiteTitle(urlItem.value); + setPlatformTitle(title); + } + } catch (error) { + console.error('Error fetching website title:', error); + } + }; + + if (data.useCases[0].platformUrl === null) { + setPlatformTitle('N/A'); + } else { + fetchTitle(); + } + }, [data?.useCases[0]?.platformUrl]); + + const PrimaryDetails = [ + { label: 'Use Case Name', value: data?.useCases[0]?.title }, + { label: 'Summary', value: data?.useCases[0]?.summary }, + { + label: 'Running Status', + value: data?.useCases[0]?.runningStatus, + }, + { label: 'Started On', value: data?.useCases[0]?.startedOn }, + { + label: 'Completed On', + value: data?.useCases[0]?.completedOn, + }, + { label: 'Sector', value: data?.useCases[0]?.sectors[0]?.name }, + { label: 'Tags', value: data?.useCases[0]?.tags[0]?.value }, + ...(data?.useCases[0]?.metadata?.map((meta: any) => ({ + label: meta.metadataItem?.label, + value: meta.value, + })) || []), + ]; + return ( +
+
+ <> + {PrimaryDetails.map( + (item, index) => + item.value && ( +
+
+ {item.label}: +
+
+ {item.value} +
+
+ ) + )} + +
+
+ Platform URL: +
+
+ + + {platformTitle?.trim() ? platformTitle : 'Visit Platform'} + + +
+
+ + {data?.useCases[0]?.logo && ( +
+
+ + Image: + +
+ +
+ )} + +
+
+ ); +}; + +export default Details; diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/page.tsx index 456f7de5..41a36310 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/[id]/publish/page.tsx @@ -1,6 +1,5 @@ 'use client'; -import Image from 'next/image'; import { useParams, useRouter } from 'next/navigation'; import { graphql } from '@/gql'; import { useMutation, useQuery } from '@tanstack/react-query'; @@ -12,14 +11,16 @@ import { Button, Icon, Spinner, - Table, Text, toast, } from 'opub-ui'; import { GraphQL } from '@/lib/api'; -import { formatDate } from '@/lib/utils'; import { Icons } from '@/components/icons'; +import Assign from './Assign'; +import Contributors from './Contributors'; +import Dashboards from './Dashboards'; +import Details from './Details'; const UseCaseDetails: any = graphql(` query UseCasedata($filters: UseCaseFilter) { @@ -28,6 +29,7 @@ const UseCaseDetails: any = graphql(` title summary website + platformUrl metadata { metadataItem { id @@ -88,6 +90,11 @@ const UseCaseDetails: any = graphql(` name } } + usecaseDashboard { + id + name + link + } } } `); @@ -104,14 +111,19 @@ const publishUseCaseMutation: any = graphql(` `); const Publish = () => { - const params = useParams(); - + const params = useParams<{ + entityType: string; + entitySlug: string; + id: string; + }>(); const UseCaseData: { data: any; isLoading: boolean; refetch: any } = useQuery( [`fetch_UsecaseDetails`], () => GraphQL( UseCaseDetails, - {}, + { + [params.entityType]: params.entitySlug, + }, { filters: { id: params.id, @@ -126,7 +138,9 @@ const Publish = () => { const router = useRouter(); const { mutate, isLoading: mutationLoading } = useMutation( - () => GraphQL(publishUseCaseMutation, {}, { useCaseId: params.id }), + () => GraphQL(publishUseCaseMutation, { + [params.entityType]: params.entitySlug, + }, { useCaseId: params.id }), { onSuccess: (data: any) => { toast('UseCase Published Successfully'); @@ -162,85 +176,17 @@ const Publish = () => { : '', }, { - name: 'Contributors', + name: 'Dashboards', data: UseCaseData?.data?.useCases[0]?.length > 0, error: '', }, - ]; - - const columns = [ - { accessorKey: 'title', header: 'Title' }, - { accessorKey: 'sector', header: 'Sector' }, - { accessorKey: 'modified', header: 'Last Modified' }, - ]; - - const PrimaryDetails = [ - { label: 'Use Case Name', value: UseCaseData.data?.useCases[0]?.title }, - { label: 'Summary', value: UseCaseData.data?.useCases[0]?.summary }, - { - label: 'Running Status', - value: UseCaseData.data?.useCases[0]?.runningStatus, - }, - { label: 'Started On', value: UseCaseData.data?.useCases[0]?.startedOn }, - { - label: 'Completed On', - value: UseCaseData.data?.useCases[0]?.completedOn, - }, - { label: 'Sector', value: UseCaseData.data?.useCases[0]?.sectors[0]?.name }, - { label: 'Tags', value: UseCaseData.data?.useCases[0]?.tags[0]?.value }, - ...(UseCaseData.data?.useCases[0]?.metadata?.map((meta: any) => ({ - label: meta.metadataItem?.label, - value: meta.value, - })) || []), - ]; - - const ContributorDetails = [ - { - label: 'Contributors', - value: - UseCaseData.data?.useCases[0]?.contributors.length > 0 - ? UseCaseData.data?.useCases[0]?.contributors - .map((item: any) => item.fullName) - .join(', ') - : 'No Contributors', - image: UseCaseData.data?.useCases[0]?.contributors, - }, - ]; - - const OrgDetails = [ - { - label: 'Supporters', - value: - UseCaseData.data?.useCases[0]?.supportingOrganizations.length > 0 - ? UseCaseData.data?.useCases[0]?.supportingOrganizations - .map((item: any) => item.name) - .join(', ') - : 'No Supporting Organizations', - image: UseCaseData.data?.useCases[0]?.supportingOrganizations, - }, { - label: 'Partners', - value: - UseCaseData.data?.useCases[0]?.partnerOrganizations.length > 0 - ? UseCaseData.data?.useCases[0]?.partnerOrganizations - .map((item: any) => item.name) - .join(', ') - : 'No Partner Organizations', - image: UseCaseData.data?.useCases[0]?.partnerOrganizations, + name: 'Contributors', + data: UseCaseData?.data?.useCases[0]?.length > 0, + error: '', }, ]; - const generateTableData = (list: Array) => { - return list?.map((item) => { - return { - title: item.title, - id: item.id, - sector: item.sectors[0]?.name, - modified: formatDate(item.modified), - }; - }); - }; - const isPublishDisabled = (useCase: any) => { if (!useCase) return true; @@ -309,132 +255,17 @@ const Publish = () => { >
{item.name === 'Assign' ? ( -
+ ) : item.name === 'Details' ? ( -
- <> - {PrimaryDetails.map( - (item, index) => - item.value && ( -
-
- - {item.label}: - -
-
- - {item.value} - -
-
- ) - )} - {UseCaseData.data?.useCases[0]?.logo && ( -
-
- - Image: - -
- -
- )} - -
+
+ ) : item.name === 'Dashboards' ? ( + ) : ( -
- {ContributorDetails.map( - (item: any, index: number) => ( -
-
- {item.label}: -
-
- {item.image.map( - (data: any, index: number) => ( -
- - - - {data.fullName} - -
- ) - )} -
-
- ) - )} - {OrgDetails.map((item: any, index: number) => ( -
-
- {item.label}: -
-
- {item.image.map( - (data: any, index: number) => ( -
-
- -
- - {data.name} - -
- ) - )} -
-
- ))} -
+ )} diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/layout.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/layout.tsx index f889c0d8..dfc05b94 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/layout.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/edit/layout.tsx @@ -33,9 +33,19 @@ const FetchUseCaseTitle: any = graphql(` const TabsAndChildren = ({ children }: { children: React.ReactNode }) => { const router = useRouter(); const pathName = usePathname(); - const params = useParams(); - - const layoutList = ['details', 'contributors', 'assign', 'publish']; + const params = useParams<{ + entityType: string; + entitySlug: string; + id: string; + }>(); + + const layoutList = [ + 'details', + 'contributors', + 'assign', + 'dashboards', + 'publish', + ]; const pathItem = layoutList.find(function (v) { return pathName.indexOf(v) >= 0; @@ -46,7 +56,9 @@ const TabsAndChildren = ({ children }: { children: React.ReactNode }) => { () => GraphQL( FetchUseCaseTitle, - {}, + { + [params.entityType]: params.entitySlug, + }, { filters: { id: params.id, @@ -61,7 +73,9 @@ const TabsAndChildren = ({ children }: { children: React.ReactNode }) => { const { mutate, isLoading: editMutationLoading } = useMutation( (data: { data: UseCaseInputPartial }) => - GraphQL(UpdateUseCaseTitleMutation, {}, data), + GraphQL(UpdateUseCaseTitleMutation, { + [params.entityType]: params.entitySlug, + }, data), { onSuccess: () => { toast('Use case updated successfully'); @@ -85,6 +99,11 @@ const TabsAndChildren = ({ children }: { children: React.ReactNode }) => { url: `/dashboard/${params.entityType}/${params.entitySlug}/usecases/edit/${params.id}/assign`, selected: pathItem === 'assign', }, + { + label: 'Dashboards', + url: `/dashboard/${params.entityType}/${params.entitySlug}/usecases/edit/${params.id}/dashboards`, + selected: pathItem === 'dashboards', + }, { label: 'Contributors', url: `/dashboard/${params.entityType}/${params.entitySlug}/usecases/edit/${params.id}/contributors`, @@ -140,9 +159,9 @@ const TabsAndChildren = ({ children }: { children: React.ReactNode }) => {
{children}
-
+
diff --git a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/page.tsx b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/page.tsx index 72a9b0a1..c05550bf 100644 --- a/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/page.tsx +++ b/app/[locale]/dashboard/[entityType]/[entitySlug]/usecases/page.tsx @@ -93,8 +93,7 @@ export default function DatasetPage({ }, order: { modified: 'DESC' }, } - ), - + ) ); useEffect(() => { @@ -183,15 +182,18 @@ export default function DatasetPage({ { accessorKey: 'title', header: 'Title', - cell: ({ row }: any) => ( - - {row.original.title} - - ), + cell: ({ row }: any) => + navigationTab === 'published' ? ( + {row.original.title} + ) : ( + + {row.original.title} + + ), }, { accessorKey: 'created', header: 'Date Created' }, { accessorKey: 'modified', header: 'Date Modified' }, diff --git a/app/[locale]/dashboard/[entityType]/page.tsx b/app/[locale]/dashboard/[entityType]/page.tsx index a099130f..649fc0d2 100644 --- a/app/[locale]/dashboard/[entityType]/page.tsx +++ b/app/[locale]/dashboard/[entityType]/page.tsx @@ -132,7 +132,7 @@ const Page = () => {
-
+
{allEntityDetails?.organizations?.map((entityItem: any) => { return (
diff --git a/app/[locale]/dashboard/components/main-footer.tsx b/app/[locale]/dashboard/components/main-footer.tsx index 9e7e37a0..c7064f34 100644 --- a/app/[locale]/dashboard/components/main-footer.tsx +++ b/app/[locale]/dashboard/components/main-footer.tsx @@ -2,7 +2,9 @@ import Image from 'next/image'; import Link from 'next/link'; import { Icon, Text } from 'opub-ui'; +import { cn } from '@/lib/utils'; import { Icons } from '@/components/icons'; +import styles from './styles.module.scss'; const MainFooter = () => { const socialMedia = [ @@ -27,7 +29,7 @@ const MainFooter = () => { <>
-
+
{' '}
@@ -66,7 +68,8 @@ const MainFooter = () => { {' '} Follow Us @@ -80,26 +83,33 @@ const MainFooter = () => { target="_blank" className=" h-10 w-10 rounded-5 bg-tertiaryAccent p-2" > - + ))}
-
-
+
+
About Us Contact Us -
-
+
made by - - + +
diff --git a/app/[locale]/dashboard/components/main-nav.tsx b/app/[locale]/dashboard/components/main-nav.tsx index 950cf1d7..5339885c 100644 --- a/app/[locale]/dashboard/components/main-nav.tsx +++ b/app/[locale]/dashboard/components/main-nav.tsx @@ -1,10 +1,11 @@ 'use client'; -import { Session } from 'next-auth'; -import { signIn, signOut, useSession } from 'next-auth/react'; +import React, { useEffect, useState } from 'react'; import Image from 'next/image'; import Link from 'next/link'; import { usePathname, useRouter } from 'next/navigation'; +import { Session } from 'next-auth'; +import { signIn, signOut, useSession } from 'next-auth/react'; import { Avatar, Button, @@ -16,11 +17,10 @@ import { Spinner, Text, } from 'opub-ui'; -import React, { useEffect, useState } from 'react'; -import { Icons } from '@/components/icons'; import { useDashboardStore } from '@/config/store'; import { GraphQL } from '@/lib/api'; +import { Icons } from '@/components/icons'; import { UserDetailsQryDoc } from '../[entityType]/[entitySlug]/schema'; import { allOrganizationsListingDoc } from '../[entityType]/schema'; import Sidebar from './sidebar'; @@ -41,7 +41,6 @@ export function MainNav({ hideSearch = false }) { const { data: session, status } = useSession(); const { setUserDetails, setAllEntityDetails } = useDashboardStore(); - async function keycloakSessionLogOut() { try { setIsLoggingOut(true); diff --git a/app/[locale]/dashboard/components/styles.module.scss b/app/[locale]/dashboard/components/styles.module.scss index ad660b82..968d87e2 100644 --- a/app/[locale]/dashboard/components/styles.module.scss +++ b/app/[locale]/dashboard/components/styles.module.scss @@ -58,6 +58,9 @@ padding-top: var(--space-5); flex-grow: 1; transition: transform var(--duration-400) ease 0s; + overflow-x: auto; + overflow-y: hidden; + max-width: 100%; @media screen and (min-width: 768px) { padding-left: 0; @@ -71,3 +74,9 @@ opacity: 0.5; pointer-events: none; } + +.FooterIcons { + svg { + stroke: black; + } +} diff --git a/components/BreadCrumbs/index.tsx b/components/BreadCrumbs/index.tsx index 4d0613ca..a162a598 100644 --- a/components/BreadCrumbs/index.tsx +++ b/components/BreadCrumbs/index.tsx @@ -14,18 +14,29 @@ interface BreadCrumbsProps { const BreadCrumbs: React.FC = ({ data }) => { return ( -
+
- + {data.map((item, index) => ( {index === data.length - 1 ? ( - {item.label} + + {item.label} + ) : ( - {item.label} + + {item.label} + )} {index < data.length - 1 && } diff --git a/package-lock.json b/package-lock.json index 4ed8cfc5..ad31f68f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "next-auth": "^4.24.7", "next-intl": "^3.4.0", "next-usequerystate": "^1.17.2", - "opub-ui": "0.3.86", + "opub-ui": "0.3.88", "react": "^18.2.0", "react-aria": "3.22.0", "react-dom": "^18.2.0", @@ -16423,9 +16423,9 @@ } }, "node_modules/opub-ui": { - "version": "0.3.86", - "resolved": "https://registry.npmjs.org/opub-ui/-/opub-ui-0.3.86.tgz", - "integrity": "sha512-MrEC3YxCM9ZThNk4B6xKvGWPmJ5GwCkQhUmY3sQorzw4lO2/ut7r0mxroJ04OSZsaPaansssfH35DHPboOseWA==", + "version": "0.3.88", + "resolved": "https://registry.npmjs.org/opub-ui/-/opub-ui-0.3.88.tgz", + "integrity": "sha512-Xpzfq8azOm1A/U7qqbRnJeWH9+XkpwzwTOpNIDEZ5N7E/efW8xZpR/fMC8kFWX0xxHpsAi6fe5zZJ8iM0V/cFA==", "dependencies": { "@ariakit/react": "^0.3.14", "@hookform/resolvers": "^3.3.4", diff --git a/package.json b/package.json index 5be0db08..9939f9ee 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "next-auth": "^4.24.7", "next-intl": "^3.4.0", "next-usequerystate": "^1.17.2", - "opub-ui": "0.3.86", + "opub-ui": "0.3.88", "react": "^18.2.0", "react-aria": "3.22.0", "react-dom": "^18.2.0", diff --git a/public/Sectors/Coastal.svg b/public/Sectors/Coastal.svg new file mode 100644 index 00000000..24a94ecb --- /dev/null +++ b/public/Sectors/Coastal.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/Sectors/Gender.svg b/public/Sectors/Gender.svg new file mode 100644 index 00000000..ee135aca --- /dev/null +++ b/public/Sectors/Gender.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/chart-bar.svg b/public/chart-bar.svg new file mode 100644 index 00000000..9964ed51 --- /dev/null +++ b/public/chart-bar.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + +