Skip to content

Commit

Permalink
merged main
Browse files Browse the repository at this point in the history
  • Loading branch information
plaume8 committed Dec 15, 2024
2 parents bbac71f + 9258b74 commit cac1655
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 74 deletions.
27 changes: 14 additions & 13 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack(config, { isServer }) {
// Add rule to handle SVG imports
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack', 'url-loader'],
});
config.resolve.alias.canvas = false;

return config;
},
};

module.exports = nextConfig;
webpack(config, { isServer }) {
// Add rule to handle SVG imports
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack', 'url-loader'],
});
config.resolve.alias.canvas = false;

return config;
},
cacheHandler: require.resolve('next/dist/server/lib/incremental-cache/file-system-cache.js'),
};

module.exports = nextConfig;
34 changes: 22 additions & 12 deletions src/app/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,35 @@

import { useEffect } from 'react';

export default function Error({ error, reset }: { error: Error; reset: () => void }) {
import { CustomButton } from '@/components/Buttons/CustomButton';
import { Topbar } from '@/components/Topbar/Topbar';

export default function Error({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
useEffect(() => {
// Log the error to an error reporting service
/* eslint-disable no-console */
console.error(error);
}, [error]);

return (
<div>
<h2>Something went wrong!</h2>
<button
type="button"
onClick={
// Attempt to recover by trying to re-render the segment
() => reset()
}
>
Try again
</button>
<div className="flex flex-col h-screen">
<Topbar />
<main className="flex h-full flex-col items-center justify-center gap-2 text-content">
<section className="text-center">
<h2 className="text-xl font-semibold">An Error Occurred</h2>
<p>Please try again or go back to the Home page.</p>
</section>
<div className="flex flex-row gap-2 mt-4">
<CustomButton variant="solid" size="lg" onClick={() => reset()}>
Try again
</CustomButton>
<a href="/">
<CustomButton variant="solid" size="lg">
Go to Home page
</CustomButton>
</a>
</div>
</main>
</div>
);
}
25 changes: 25 additions & 0 deletions src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
'use client';

import { CustomButton } from '@/components/Buttons/CustomButton';
import { Topbar } from '@/components/Topbar/Topbar';

export default function NotFound() {
return (
<div className="flex flex-col h-screen">
<Topbar />
<main className="flex h-full flex-col items-center justify-center gap-2 text-content">
<section className="text-center">
<h2 className="text-xl font-semibold">Ooops</h2>
<p>The requested page could not be found.</p>
</section>
<div className="flex flex-row gap-2 mt-4">
<a href="/">
<CustomButton variant="solid" size="lg">
Go to Home page
</CustomButton>
</a>
</div>
</main>
</div>
);
}
48 changes: 37 additions & 11 deletions src/components/Legend/GradientLegend.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import clsx from 'clsx';

import { ColorsData } from '@/domain/props/ColorsData';
import GradientLegendProps from '@/domain/props/GradientLegendProps';

export default function GradientLegend({ colors, startLabel, endLabel, hasNotAnalyzedPoint }: GradientLegendProps) {
const gradients: string = colors
.map((color: string, index: number) => {
const percentage = (index / (colors.length - 1)) * 100;
return `hsl(var(--nextui-${color})) ${percentage}%`;
import { Tooltip } from '../Tooltip/Tooltip';

export default function GradientLegend({ colorsData, startLabel, endLabel, hasNotAnalyzedPoint }: GradientLegendProps) {
const gradients: string = colorsData
.map((colorData: ColorsData, index: number) => {
const percentage = (index / (colorsData.length - 1)) * 100;
return `hsl(var(--nextui-${colorData.color})) ${percentage}%`;
})
.join(', ');

const segmentWidth: number = 100 / colorsData.length;

return (
<div className="relative flex flex-col items-end w-full md:w-96 px-4 py-3">
{hasNotAnalyzedPoint && (
Expand All @@ -20,12 +27,31 @@ export default function GradientLegend({ colors, startLabel, endLabel, hasNotAna
</div>
)}

<div
className="flex items-center w-full h-2 rounded-full"
style={{
background: `linear-gradient(90deg, ${gradients})`,
}}
/>
<div className="relative w-full h-2 rounded-full" style={{ background: `linear-gradient(90deg, ${gradients})` }}>
{colorsData.map((colorData, index) => (
<div
key={colorData.color}
className="absolute top-0 left-0 h-full"
style={{
width: `${segmentWidth}%`,
left: `${index * segmentWidth}%`,
}}
>
<Tooltip title={colorData.title} text={colorData.value} titleStyle="text-center" textStyle="text-center">
<div
className={clsx('hover:bg-opacity-25 hover:bg-black group flex-1 h-full cursor-pointer', {
'rounded-l-full': index === 0,
'rounded-r-full': index === colorsData.length - 1,
})}
style={{
flexBasis: `${segmentWidth}%`,
}}
/>
</Tooltip>
</div>
))}
</div>

<div className="flex justify-between w-full mt-2 text-xs font-medium">
<span>{startLabel}</span>
<span>{endLabel}</span>
Expand Down
3 changes: 3 additions & 0 deletions src/components/Map/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ export default function Map({ countries, disputedAreas, fcsData, alertData }: Ma
setRegionNutritionData,
setIpcRegionData
);
window.gtag('event', `${selectedCountryData.properties.iso3}_country_selected`, {
selectedMap: selectedMapType,
});
setSelectedCountryName(selectedCountryData.properties.adm0_name);
mapRef.current?.fitBounds(L.geoJSON(selectedCountryData as GeoJSON).getBounds(), { animate: true });
}
Expand Down
11 changes: 7 additions & 4 deletions src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Tooltip as NextUITooltip } from '@nextui-org/tooltip';
import clsx from 'clsx';

import TooltipProps from '@/domain/props/TooltipProps';

Expand All @@ -11,9 +12,11 @@ import TooltipProps from '@/domain/props/TooltipProps';
* @param text textual content of the tooltip
* @param delay delay with which tooltip appears on hover in milliseconds; default is 0
* @param warning selected if the tooltip should be highlighted (optional)
* @param titleStyle tailwind classes to style the title (optional)
* @param textStyle tailwind classes to style the text (optional)
* @constructor
*/
export function Tooltip({ children, title, text, delay, warning }: TooltipProps) {
export function Tooltip({ children, title, text, delay, warning, titleStyle, textStyle }: TooltipProps) {
const OFFSET: number = 10;
const RADIUS = 'sm';
const SHADOW = 'md';
Expand All @@ -23,11 +26,11 @@ export function Tooltip({ children, title, text, delay, warning }: TooltipProps)

const tooltipContent = title ? (
<div>
<h3 className="text-small font-bold mb-1"> {title} </h3>
<p className="text-small font-normal"> {text} </p>
<h3 className={clsx('text-small font-bold mb-1', titleStyle)}> {title} </h3>
<p className={clsx('text-small font-normal', textStyle)}> {text} </p>
</div>
) : (
<p className="text-small font-normal"> {text} </p>
<p className={`text-small font-normal ${textStyle}`}> {text} </p>
);

return (
Expand Down
76 changes: 46 additions & 30 deletions src/domain/constant/legend/mapLegendData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,15 @@ export function mapLegendData(
case GlobalInsight.FOOD:
legendData.push({
title: 'Prevalence of insufficient food consumption',
colors: ['fcsGradient1', 'fcsGradient2', 'fcsGradient3', 'fcsGradient4', 'fcsGradient5', 'fcsGradient6'],
colorsData: [
{ color: 'fcsGradient1', title: 'Very Low', value: '0-5%' },
{ color: 'fcsGradient2', title: 'Low', value: '5-10%' },
{ color: 'fcsGradient3', title: 'Moderately Low', value: '10-20%' },
{ color: 'fcsGradient4', title: 'Moderately High', value: '20-30%' },
{ color: 'fcsGradient5', title: 'High', value: '30-40%' },
{ color: 'fcsGradient6', title: 'Very High', value: 'Above 40%' },
],

startLabel: '0%',
endLabel: 'above 40%',
popoverInfo: (
Expand Down Expand Up @@ -158,17 +166,18 @@ export function mapLegendData(
case GlobalInsight.RAINFALL:
legendData.push({
title: 'Rainfall',
colors: [
'vegetationGradient1',
'vegetationGradient2',
'vegetationGradient3',
'vegetationGradient4',
'vegetationGradient5',
'rainfallGradient6',
'rainfallGradient7',
'rainfallGradient8',
'rainfallGradient9',
colorsData: [
{ color: 'vegetationGradient1', value: '<40%' },
{ color: 'vegetationGradient2', value: '40-60%' },
{ color: 'vegetationGradient3', value: '60-80%' },
{ color: 'vegetationGradient4', value: '80-90%' },
{ color: 'vegetationGradient5', value: '90-110%' },
{ color: 'rainfallGradient6', value: '110-120%' },
{ color: 'rainfallGradient7', value: '120-140%' },
{ color: 'rainfallGradient8', value: '140-180%' },
{ color: 'rainfallGradient9', value: '>180%' },
],

startLabel: '<40%',
endLabel: '>180%',
popoverInfo: (
Expand Down Expand Up @@ -196,17 +205,18 @@ export function mapLegendData(
case GlobalInsight.VEGETATION:
legendData.push({
title: 'Vegetation',
colors: [
'vegetationGradient1',
'vegetationGradient2',
'vegetationGradient3',
'vegetationGradient4',
'vegetationGradient5',
'vegetationGradient6',
'vegetationGradient7',
'vegetationGradient8',
'vegetationGradient9',
colorsData: [
{ color: 'vegetationGradient1', value: '<50%' },
{ color: 'vegetationGradient2', value: '50-70%' },
{ color: 'vegetationGradient3', value: '70-80%' },
{ color: 'vegetationGradient4', value: '80-90%' },
{ color: 'vegetationGradient5', value: '90-110%' },
{ color: 'vegetationGradient6', value: '110-120%' },
{ color: 'vegetationGradient7', value: '120-130%' },
{ color: 'vegetationGradient8', value: '130-150%' },
{ color: 'vegetationGradient9', value: '>150%' },
],

startLabel: '<50%',
endLabel: '>150%',
popoverInfo: (
Expand Down Expand Up @@ -236,14 +246,14 @@ export function mapLegendData(
legendData.push({
title: 'Number of people in IPC/CH Phase 3 or above (millions)',
hasNotAnalyzedPoint: true,
colors: [
'ipcGradient1',
'ipcGradient2',
'ipcGradient3',
'ipcGradient4',
'ipcGradient5',
'ipcGradient6',
'ipcGradient7',
colorsData: [
{ color: 'ipcGradient1', value: '0-0.099' },
{ color: 'ipcGradient2', value: '0.1-0.49' },
{ color: 'ipcGradient3', value: '0.5-0.99' },
{ color: 'ipcGradient4', value: '1.0-2.99' },
{ color: 'ipcGradient5', value: '3.0-4.99' },
{ color: 'ipcGradient6', value: '5.0-9.99' },
{ color: 'ipcGradient7', value: '>10' },
],
startLabel: '0',
endLabel: '>10',
Expand Down Expand Up @@ -356,7 +366,13 @@ export function mapLegendData(
} else {
legendData.push({
title: 'Risk of Inadequate Micronutrient Intake',
colors: ['ipcGradient1', 'ipcGradient2', 'ipcGradient3', 'ipcGradient4', 'ipcGradient5'],
colorsData: [
{ color: 'ipcGradient1', title: 'Lowest', value: '0-19%' },
{ color: 'ipcGradient2', title: 'Low', value: '20-39%' },
{ color: 'ipcGradient3', title: 'Moderate', value: '40-59%' },
{ color: 'ipcGradient4', title: 'High', value: '60-79%' },
{ color: 'ipcGradient5', title: 'Highest', value: '80-100%' },
],
startLabel: '0%',
endLabel: '100%',
popoverInfo: (
Expand Down
5 changes: 5 additions & 0 deletions src/domain/props/ColorsData.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ColorsData {
color: string;
title?: string;
value: string;
}
4 changes: 3 additions & 1 deletion src/domain/props/GradientLegendContainerItem.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { ReactNode } from 'react';

import { ColorsData } from './ColorsData';

export interface GradientLegendContainerItem {
colors: string[];
colorsData: ColorsData[];
title: string;
startLabel: string;
endLabel: string;
Expand Down
4 changes: 3 additions & 1 deletion src/domain/props/GradientLegendProps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ColorsData } from './ColorsData';

export default interface GradientLegendProps {
colors: string[];
colorsData: ColorsData[];
startLabel: string;
endLabel: string;
hasNotAnalyzedPoint?: boolean;
Expand Down
2 changes: 2 additions & 0 deletions src/domain/props/TooltipProps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ export default interface TooltipProps {
text: string;
delay?: number;
warning?: boolean;
titleStyle?: string;
textStyle?: string;
}
4 changes: 2 additions & 2 deletions src/operations/legends/LegendOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export class LegendOperations {
return false;
}
return (
Array.isArray((value as GradientLegendContainerItem).colors) &&
(value as GradientLegendContainerItem).colors.every((color) => typeof color === 'string')
Array.isArray((value as GradientLegendContainerItem).colorsData) &&
(value as GradientLegendContainerItem).colorsData.every((colorsData) => typeof colorsData.color === 'string')
);
}
}

0 comments on commit cac1655

Please sign in to comment.