Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/total tainings #146

Merged
merged 6 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"class-variance-authority": "^0.6.0",
"clsx": "^1.2.1",
"cmdk": "0.2.1",
"country-iso-3-to-2": "^1.1.1",
"d3-array": "3.2.4",
"deck.gl": "8.9.19",
"eslint": "8.42.0",
Expand All @@ -67,7 +68,6 @@
"react-map-gl": "7.0.25",
"react-markdown": "9.0.1",
"react-share": "5.1.0",
"react-world-flags": "1.6.0",
"recharts": "2.12.1",
"remark-gfm": "4.0.0",
"rooks": "7.14.1",
Expand Down
44 changes: 44 additions & 0 deletions client/src/components/flag/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Image from 'next/image';

const DEFAULT_CDN_URL = 'https://cdn.jsdelivr.net/gh/lipis/flag-icons/flags/4x3/';
const DEFAULT_CDN_SUFFIX = 'svg';

interface ImgProps extends React.ImgHTMLAttributes<HTMLImageElement> {
cdnSuffix?: string;
cdnUrl?: string;
countryCode: string;
width?: number;
height?: number;
svg?: true;
}

export type CountryFlagProps = ImgProps;

export const CountryFlag = ({
cdnSuffix = DEFAULT_CDN_SUFFIX,
cdnUrl = DEFAULT_CDN_URL,
countryCode,
height = 26.66,
width = 40,
svg = true,
className,
}: CountryFlagProps) => {
if (typeof countryCode !== 'string') {
return null;
}
if (svg) {
const flagUrl = `${cdnUrl}${countryCode.toLowerCase()}.${cdnSuffix}`;

return (
<Image
alt={'Flag of ' + countryCode}
src={flagUrl}
width={width}
height={height}
className={className}
/>
);
}
};

export default CountryFlag;
2 changes: 2 additions & 0 deletions client/src/containers/countries/detail/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ export const COLUMNS = [
'forest_area_pct',
'intervention_area_total',
'jobs',
'total_trainings',
'trainees',
'jobs_total',
'net_flux_co2e_year',
'production_ntfp_total',
Expand Down
43 changes: 25 additions & 18 deletions client/src/containers/countries/detail/panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import { useEffect } from 'react';

import Markdown from 'react-markdown';
import Flag from 'react-world-flags';

import Image from 'next/image';
import Link from 'next/link';
import { notFound, useParams } from 'next/navigation';

import getCountryIso2 from 'country-iso-3-to-2';
import { useSetAtom } from 'jotai';
import { X } from 'lucide-react';
import { ArrowLeft, Download, ExternalLink, Info } from 'lucide-react';
Expand Down Expand Up @@ -37,6 +37,7 @@ import { usefulLinksCountry } from '@/containers/countries/detail/constants';
import { COLUMNS, CSV_COLUMNS_ORDER } from '@/containers/countries/detail/constants';
import Share from '@/containers/share';

import CountryFlag from '@/components/flag';
import { Button } from '@/components/ui/button';
import { Dialog, DialogClose, DialogContent, DialogTrigger } from '@/components/ui/dialog';
import ContentLoader from '@/components/ui/loader';
Expand Down Expand Up @@ -195,11 +196,13 @@ export default function CountryDetailPanel() {
<ScrollArea className="h-full px-5">
<div className="mt-16 flex items-center space-x-3 pt-7">
{data?.data?.attributes?.iso && (
<Flag
code={data?.data?.attributes.iso}
height="40"
width="48"
<CountryFlag
alt={data.data?.attributes.iso}
countryCode={getCountryIso2(data.data?.attributes.iso || '') || ''}
key={`${data.data?.attributes.iso}`}
className="rounded"
width={48}
height={32}
/>
)}
<h2 className="text-xl" data-cy="country-detail-name">
Expand All @@ -220,11 +223,13 @@ export default function CountryDetailPanel() {
<div className="flex flex-col space-y-8 px-4">
<div className="mt-4 flex space-x-2">
{data?.data?.attributes?.iso && (
<Flag
code={data?.data?.attributes.iso}
height="32"
width="40"
<CountryFlag
alt={data.data?.attributes.iso}
countryCode={getCountryIso2(data.data?.attributes.iso || '') || ''}
key={`${data.data?.attributes.iso}`}
className="rounded"
width={48}
height={32}
/>
)}
<p>{data?.data?.attributes?.name}</p>
Expand Down Expand Up @@ -435,7 +440,7 @@ export default function CountryDetailPanel() {
</div>
<div className="w-full rounded-xl bg-white p-4 shadow-sm">
<div className="flex items-center justify-between pb-2">
<h3 className="text-base text-green-800">Total jobs</h3>
<h3 className="text-base text-green-800">Total trainings</h3>
<Tooltip delayDuration={200}>
<TooltipTrigger className="flex items-center justify-center rounded-full p-2 hover:bg-yellow-50 data-[state=open]:bg-yellow-50">
<Info className="text-green-800" size={20} />
Expand All @@ -444,24 +449,26 @@ export default function CountryDetailPanel() {
<TooltipContent className="max-w-[200px] p-2">
<p className="text-sm text-yellow-900">
<Markdown remarkPlugins={[remarkGfm]} className="prose text-xs">
The total number of short- and long-term jobs generated by the
project interventions in the AFoCO Member Countries.
The total number of training activities conducted and participants
in the AFoCO Member Countries.
</Markdown>
</p>
</TooltipContent>
</Tooltip>
</div>

<p className="py-4 text-3xl font-extrabold">
{formatCompactNumber(indicators.jobs_total['value'])}
{formatCompactNumber(indicators.trainings_total['value'])}
</p>
{indicators.jobs && (
{indicators.trainees && (
<div className="h-44">
<BarsChart
data={Object.entries(indicators.jobs['value']).map(([year, uv]) => ({
year,
uv,
}))}
data={Object.entries(indicators.trainees['value']).map(
([year, uv]) => ({
year,
uv,
})
)}
barDataKey="uv"
barRadius={[20, 20, 20, 20]}
fillBar="#70B6CC"
Expand Down
16 changes: 13 additions & 3 deletions client/src/containers/countries/item.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
'use client';

import Flag from 'react-world-flags';

import Link from 'next/link';

import getCountryIso2 from 'country-iso-3-to-2';

import { useGetCountryIndicatorFields } from '@/types/generated/country-indicator-field';
import { CountryListResponseDataItem } from '@/types/generated/strapi.schemas';

import { useSyncQueryParams } from '@/hooks/datasets';

import CountryFlag from '@/components/flag';

export default function CountryItem({ data }: { data: CountryListResponseDataItem }) {
const queryParams = useSyncQueryParams({ bbox: true });

Expand All @@ -35,7 +37,15 @@ export default function CountryItem({ data }: { data: CountryListResponseDataIte
>
<div className="flex items-center space-x-4">
{data.attributes?.iso && (
<Flag code={data.attributes.iso} height="32" width="40" className="rounded" />
<CountryFlag
alt={data.attributes.iso}
countryCode={getCountryIso2(data.attributes.iso || '') || ''}
key={`${data.attributes.iso}`}
className="rounded"
style={{
fontSize: '3em',
}}
/>
)}

<h3>{data.attributes?.name}</h3>
Expand Down
4 changes: 2 additions & 2 deletions client/src/containers/countries/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
// import { useState } from 'react';

// import { Search, X } from 'lucide-react';
import { ExternalLink } from 'lucide-react';

import { useGetCountries } from '@/types/generated/country';

import CountryItem from '@/containers/countries/item';
import { usefulLinksCountriesList } from '@/containers/countries/detail/constants';
import CountryItem from '@/containers/countries/item';

// import { Input } from '@/components/ui/input';
import ContentLoader from '@/components/ui/loader';
import { ScrollArea } from '@/components/ui/scroll-area';
import { ExternalLink } from 'lucide-react';

export default function CountriesList() {
// const [searchValue, setSearchValue] = useState<string | null>(null);
Expand Down
64 changes: 48 additions & 16 deletions client/src/containers/datasets/layers/projects/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,21 @@ export function useLayers({

// Reactivity to Hover Events in the Sidebar:
// Similarly, When a user hovers over the a project in the sidebar, both point and geometry representations within the layer are programmed to change in color and/or size.

const sanitizedProjects = filteredProjects.filter((project) => project !== null);

const filter =
sanitizedProjects.length > 0
? ['in', ['get', 'project_code'], ['literal', sanitizedProjects]]
: ['!=', ['get', 'project_code'], null];

return [
{
id: 'projects_points_shadow',
type: 'circle',
filter: ['in', ['get', 'project_code'], ['literal', filteredProjects]],
filter,
source: 'projects',
'source-layer': 'areas_centroids_c',
'source-layer': 'areas_centroids_c_v202410',
paint: {
'circle-radius': 16,
'circle-color': '#ccc',
Expand All @@ -163,18 +171,18 @@ export function useLayers({
{
id: 'projects_circle',
type: 'circle',
filter: ['in', ['get', 'project_code'], ['literal', filteredProjects]],
filter,
source: 'projects',
'source-layer': 'areas_centroids_c',
'source-layer': 'areas_centroids_c_v202410',
paint: {
'circle-stroke-color': '#ffffff',
'circle-stroke-width': [
'case',
['boolean', ['feature-state', 'hover'], false],
3,
['==', ['get', 'project_code'], hoveredProject],
['==', ['get', 'project_code'], hoveredProject?.[0] || null],
7,
['!=', ['get', 'project_code'], hoveredProject],
['!=', ['get', 'project_code'], hoveredProject?.[0] || null],
3,
7,
],
Expand All @@ -193,19 +201,35 @@ export function useLayers({
'case',
['boolean', ['feature-state', 'hover'], false],
1,
['all', ['to-boolean', hoveredProject], ['!=', ['get', 'project_code'], hoveredProject]],
[
'all',
['to-boolean', hoveredProject?.[0] || null],
['!=', ['get', 'project_code'], hoveredProject?.[0] || null],
],
0.2,
['all', ['to-boolean', hoveredProject], ['==', ['get', 'project_code'], hoveredProject]],
[
'all',
['to-boolean', hoveredProject?.[0] || null],
['==', ['get', 'project_code'], hoveredProject?.[0] || null],
],
1,
opacity,
],
'circle-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
1,
['all', ['to-boolean', hoveredProject], ['!=', ['get', 'project_code'], hoveredProject]],
[
'all',
['to-boolean', hoveredProject?.[0] || null],
['!=', ['get', 'project_code'], hoveredProject?.[0] || null],
],
0.2,
['all', ['to-boolean', hoveredProject], ['==', ['get', 'project_code'], hoveredProject]],
[
'all',
['to-boolean', hoveredProject?.[0] || null],
['==', ['get', 'project_code'], hoveredProject?.[0] || null],
],
1,
opacity,
],
Expand All @@ -218,18 +242,26 @@ export function useLayers({
{
id: 'projects_fill',
type: 'fill',
filter: ['in', ['get', 'project_code'], ['literal', filteredProjects]],
filter,
source: 'projects',
'source-layer': 'areas_centroids_l',
'source-layer': 'areas_centroids_l_v202410',
paint: {
'fill-color': '#176252',
'fill-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
0.7,
['all', ['to-boolean', hoveredProject], ['!=', ['get', 'project_code'], hoveredProject]],
[
'all',
['to-boolean', hoveredProject?.[0] || null],
['!=', ['get', 'project_code'], hoveredProject?.[0] || null],
],
0.2,
['all', ['to-boolean', hoveredProject], ['==', ['get', 'project_code'], hoveredProject]],
[
'all',
['to-boolean', hoveredProject?.[0] || null],
['==', ['get', 'project_code'], hoveredProject?.[0] || null],
],
0.7,
opacity * 0.7,
],
Expand All @@ -242,9 +274,9 @@ export function useLayers({
{
id: 'projects_line',
type: 'line',
filter: ['in', ['get', 'project_code'], ['literal', filteredProjects]],
filter,
source: 'projects',
'source-layer': 'areas_centroids_l',
'source-layer': 'areas_centroids_l_v202410',
paint: {
'line-color': '#B45F06',
'line-opacity': opacity,
Expand Down
2 changes: 1 addition & 1 deletion client/src/containers/datasets/layers/projects/layer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useLayers } from './hooks';
const SOURCE: SourceProps = {
promoteId: 'project_code',
type: 'vector',
url: 'mapbox://afoco.25x9bxct',
url: 'mapbox://afoco.06cjgob1',
id: 'projects',
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const TreeCoverLossSettings: React.FC<TreeCoverLossSettings> = ({
description,
startYear: startYearValue,
endYear: endYearValue,
paramsConfig,
onChangeSettings,
}) => {
// const startYear = useMemo(
Expand Down
Loading