Skip to content

Commit a2fb06e

Browse files
Merge pull request #226 from CivicDataLab/225-add-use-case-listing-and-detail-page
Update Usecase creation flow and add Usecases listing and detail pages
2 parents 58d7d81 + 1fa0662 commit a2fb06e

File tree

14 files changed

+1148
-42
lines changed

14 files changed

+1148
-42
lines changed

app/[locale]/(user)/components/ListingComponent.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
Tray,
1515
} from 'opub-ui';
1616

17-
import { cn } from '@/lib/utils';
17+
import { cn, formatDate } from '@/lib/utils';
1818
import BreadCrumbs from '@/components/BreadCrumbs';
1919
import { Icons } from '@/components/icons';
2020
import Filter from '../datasets/components/FIlter/Filter';
@@ -204,7 +204,6 @@ const ListingComponent: React.FC<ListingProps> = ({
204204
categoryDescription,
205205
categoryImage,
206206
}) => {
207-
console.log(categoryName);
208207

209208
const [facets, setFacets] = useState<{
210209
results: any[];
@@ -453,7 +452,7 @@ const ListingComponent: React.FC<ListingProps> = ({
453452
{
454453
icon: Icons.calendar,
455454
label: 'Date',
456-
value: '19 July 2024',
455+
value: formatDate(item.modified),
457456
},
458457
{
459458
icon: Icons.download,

app/[locale]/(user)/datasets/[datasetIdentifier]/components/PrimaryData/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ interface PrimaryDataProps {
1414
}
1515

1616
const PrimaryData: React.FC<PrimaryDataProps> = ({ data, isLoading }) => {
17-
console.log(data);
1817

1918
const [open, setOpen] = useState(false);
2019

app/[locale]/(user)/page.module.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,12 @@
1212
border-radius: 8px;
1313
}
1414
}
15+
16+
.Card {
17+
> a > img {
18+
@media screen and (max-width: 1400px) {
19+
width: 80%;
20+
height: 60%;
21+
}
22+
}
23+
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
'use client';
2+
3+
import { useParams } from 'next/navigation';
4+
import { graphql } from '@/gql';
5+
import { TypeDataset, TypeUseCase } from '@/gql/generated/graphql';
6+
import { useQuery } from '@tanstack/react-query';
7+
import { Card, Spinner, Text } from 'opub-ui';
8+
9+
import { GraphQL } from '@/lib/api';
10+
import BreadCrumbs from '@/components/BreadCrumbs';
11+
import PrimaryDetails from '../components/Details';
12+
import Metadata from '../components/Metadata';
13+
import { Icons } from '@/components/icons';
14+
import { formatDate } from '@/lib/utils';
15+
import { Loading } from '@/components/loading';
16+
17+
const UseCasedetails: any = graphql(`
18+
query UseCasedetails($pk: ID!) {
19+
useCase(pk: $pk) {
20+
id
21+
title
22+
summary
23+
website
24+
metadata {
25+
metadataItem {
26+
id
27+
label
28+
dataType
29+
}
30+
id
31+
value
32+
}
33+
sectors {
34+
id
35+
name
36+
}
37+
runningStatus
38+
tags {
39+
id
40+
value
41+
}
42+
publishers {
43+
name
44+
logo {
45+
path
46+
}
47+
}
48+
logo {
49+
name
50+
path
51+
url
52+
}
53+
datasets {
54+
title
55+
id
56+
downloadCount
57+
description
58+
organization {
59+
name
60+
logo {
61+
path
62+
}
63+
}
64+
metadata {
65+
metadataItem {
66+
id
67+
label
68+
dataType
69+
}
70+
id
71+
value
72+
}
73+
sectors {
74+
name
75+
}
76+
modified
77+
}
78+
contactEmail
79+
status
80+
slug
81+
}
82+
}
83+
`);
84+
85+
const UseCaseDetailPage = () => {
86+
const params = useParams();
87+
const {
88+
data: UseCaseDetails,
89+
isLoading,
90+
refetch,
91+
} = useQuery<{ useCase: TypeUseCase }>(
92+
[`fetch_UsecaseDetails_${params.useCaseSlug}`],
93+
() =>
94+
GraphQL(
95+
UseCasedetails,
96+
{},
97+
{
98+
pk: params.useCaseSlug,
99+
}
100+
),
101+
{
102+
refetchOnMount: true,
103+
refetchOnReconnect: true,
104+
}
105+
);
106+
const datasets = UseCaseDetails?.useCase?.datasets || []; // Fallback to an empty array
107+
108+
return (
109+
<div>
110+
{isLoading ? (
111+
<div className=" flex justify-center p-10">
112+
<Loading />
113+
</div>
114+
) : (
115+
<>
116+
<BreadCrumbs
117+
data={[
118+
{ href: '/', label: 'Home' },
119+
{ href: '/usecases', label: 'Use Cases' },
120+
{ href: '#', label: UseCaseDetails?.useCase?.title || '' },
121+
]}
122+
/>
123+
<div className=" bg-onSurfaceDefault">
124+
<div className="flex flex-row">
125+
<div className="w-full border-r-2 border-solid border-greyExtralight p-8 lg:w-3/4 lg:p-10">
126+
<PrimaryDetails data={UseCaseDetails} isLoading={isLoading} />
127+
</div>
128+
<div className="hidden lg:block lg:w-1/4">
129+
<Metadata data={UseCaseDetails} />
130+
</div>
131+
</div>
132+
<div className="p-8 lg:p-14">
133+
<div className=" flex flex-col gap-1">
134+
<Text variant="heading3xl">Datasets in this Use Case</Text>
135+
<Text variant="headingLg" fontWeight="regular">
136+
All Datasets related to this Use Case
137+
</Text>
138+
</div>
139+
<div className="grid w-full grid-cols-1 gap-6 pt-10 md:grid-cols-2 lg:grid-cols-3">
140+
{datasets.length > 0 &&
141+
datasets.map(
142+
(dataset: TypeDataset) => (
143+
<Card
144+
key={dataset.id}
145+
title={dataset.title}
146+
variation={'collapsed'}
147+
iconColor={'warning'}
148+
metadataContent={[
149+
{
150+
icon: Icons.calendar,
151+
label: 'Date',
152+
value: formatDate(dataset.modified),
153+
},
154+
{
155+
icon: Icons.download,
156+
label: 'Download',
157+
value: dataset.downloadCount.toString(),
158+
},
159+
{
160+
icon: Icons.globe,
161+
label: 'Geography',
162+
value: dataset.metadata?.find(
163+
(meta: any) => meta.metadataItem?.label === 'Geography'
164+
)?.value || '',
165+
},
166+
]}
167+
href={`/datasets/${dataset.id}`}
168+
footerContent={[
169+
{
170+
icon: `/Sectors/${dataset.sectors[0].name}.svg`,
171+
label: 'Sectors',
172+
},
173+
{ icon: '/fallback.svg', label: 'Published by' },
174+
]}
175+
description={dataset.description || ''}
176+
/>
177+
)
178+
)}
179+
</div>
180+
</div>
181+
</div>
182+
</>
183+
)}
184+
</div>
185+
);
186+
};
187+
188+
export default UseCaseDetailPage;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
'use client';
2+
3+
import React, { useState } from 'react';
4+
import Image from 'next/image';
5+
import { Button, Icon, Spinner, Tag, Text, Tray } from 'opub-ui';
6+
7+
import { Icons } from '@/components/icons';
8+
import Metadata from './Metadata';
9+
10+
const PrimaryDetails = ({ data, isLoading }: { data: any; isLoading: any }) => {
11+
const [open, setOpen] = useState(false);
12+
13+
return (
14+
<div>
15+
<div>
16+
<Text variant="heading2xl">{data.useCase.title}</Text>
17+
</div>
18+
<div className="mt-4 flex flex-wrap gap-2">
19+
{data.useCase.tags.map((item: any, index: number) => (
20+
<div key={index}>
21+
<Tag>{item.value}</Tag>
22+
</div>
23+
))}
24+
</div>
25+
<div
26+
className="mt-6 flex sm:block md:block lg:hidden"
27+
title="About the Dataset"
28+
>
29+
<Tray
30+
size="narrow"
31+
open={open}
32+
onOpenChange={setOpen}
33+
trigger={
34+
<div>
35+
<Button
36+
kind="tertiary"
37+
className="lg:hidden"
38+
onClick={(e) => setOpen(true)}
39+
>
40+
<div className="flex items-center gap-2 py-2">
41+
<Icon source={Icons.info} size={24} color="default" />
42+
<Text>Metadata</Text>
43+
</div>
44+
</Button>
45+
</div>
46+
}
47+
>
48+
{isLoading ? (
49+
<div className=" mt-8 flex justify-center">
50+
<Spinner />
51+
</div>
52+
) : (
53+
<Metadata data={data} setOpen={setOpen} />
54+
)}
55+
</Tray>
56+
</div>
57+
<div className="mt-6 lg:mt-10">
58+
<Image
59+
src={`${process.env.NEXT_PUBLIC_BACKEND_URL}/${data.useCase.logo?.path.replace('/code/files/', '')}`}
60+
alt={data.useCase.title}
61+
width={100}
62+
height={100}
63+
className="h-full w-full"
64+
/>
65+
</div>
66+
<div className=' lg:p-4'>
67+
<div className="mt-6 lg:mt-10">
68+
<Text variant="heading2xl">GEOGRAPHIES</Text>
69+
<div className="mt-4">
70+
<Tag>
71+
{
72+
data.useCase.metadata?.find(
73+
(meta: any) => meta.metadataItem?.label === 'Geography'
74+
)?.value
75+
}
76+
</Tag>
77+
</div>
78+
</div>
79+
<div className="mt-6 lg:mt-10">
80+
<Text variant="heading2xl">Summary</Text>
81+
<div className="mt-4">
82+
<Text variant="headingLg" fontWeight="regular">
83+
{data.useCase.summary}
84+
</Text>
85+
</div>
86+
</div>
87+
</div>
88+
</div>
89+
);
90+
};
91+
92+
export default PrimaryDetails;

0 commit comments

Comments
 (0)