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

feat: year in review reports #150

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
13 changes: 10 additions & 3 deletions src/app/download-portal/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import AccordionContainer from '@/components/Accordions/AccordionContainer';
import { TITLE } from '@/domain/entities/download/Country';
import {
COUNTRY_REPORTS_TITLE,
EXPORT_COUNTRY_DATA_TITLE,
YEAR_IN_REVIEW_REPORTS_TITLE,
} from '@/operations/download-portal/DownloadPortalConstants';

export default function Loading() {
const loading = true;
Expand All @@ -10,10 +14,13 @@ export default function Loading() {
<AccordionContainer
items={[
{
title: 'Country Reports',
title: YEAR_IN_REVIEW_REPORTS_TITLE,
},
{
title: TITLE,
title: COUNTRY_REPORTS_TITLE,
},
{
title: EXPORT_COUNTRY_DATA_TITLE,
},
]}
loading={loading}
Expand Down
23 changes: 19 additions & 4 deletions src/app/download-portal/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import AccordionContainer from '@/components/Accordions/AccordionContainer';
import DownloadCountryAccordion from '@/components/DownloadCountryAccordions/DownloadCountryAccordions';
import CountryReports from '@/components/DownloadPortal/CountryReports';
import YearInReviewReports from '@/components/DownloadPortal/YearInReviewReports';
import container from '@/container';
import { TITLE } from '@/domain/entities/download/Country';
import { GlobalDataRepository } from '@/domain/repositories/GlobalDataRepository';
import {
COUNTRY_REPORTS_TITLE,
EXPORT_COUNTRY_DATA_TITLE,
YEAR_IN_REVIEW_REPORTS_TITLE,
} from '@/operations/download-portal/DownloadPortalConstants';

export default async function DownloadPortal() {
const globalRepo = container.resolve<GlobalDataRepository>('GlobalDataRepository');
const countryMapDataPromise = globalRepo.getMapDataForCountries();
const countryCodesPromise = globalRepo.getCountryCodes();
const [countryCodesData, countryMapData] = await Promise.all([countryCodesPromise, countryMapDataPromise]);
const yearInReviewsPromise = globalRepo.getYearInReviews();
const [countryCodesData, countryMapData, yearInReviews] = await Promise.all([
countryCodesPromise,
countryMapDataPromise,
yearInReviewsPromise,
]);

const countries =
countryMapData?.features.map((feature) => ({
Expand All @@ -24,13 +34,18 @@ export default async function DownloadPortal() {
<h1>Download Portal</h1>
<div>
<AccordionContainer
multipleSelectionMode
items={[
{
title: 'Country Reports',
title: YEAR_IN_REVIEW_REPORTS_TITLE,
content: <YearInReviewReports yearInReviewReports={yearInReviews} />,
},
{
title: COUNTRY_REPORTS_TITLE,
content: <CountryReports countryCodesData={countryCodesData} />,
},
{
title: TITLE,
title: EXPORT_COUNTRY_DATA_TITLE,
content: <DownloadCountryAccordion countries={countries} />,
},
]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ import React, { useState } from 'react';
import container from '@/container';
import { DOWNLOAD_DATA } from '@/domain/constant/subscribe/Subscribe';
import { useSnackbar } from '@/domain/contexts/SnackbarContext';
import { SNACKBAR_SHORT_DURATION } from '@/domain/entities/snackbar/Snackbar';
import { SnackbarPosition, SnackbarStatus } from '@/domain/enums/Snackbar';
import { SubmitStatus } from '@/domain/enums/SubscribeTopic';
import DownloadCountryAccordionProps from '@/domain/props/DownloadCountryAccordionProps';
import DownloadRepository from '@/domain/repositories/DownloadRepository';
import {
COUNTRY_ERROR_MSG,
DATE_RANGE_ERROR_MSG,
DATE_RANGE_TOO_LONG_ERROR_MSG,
DESCRIPTION,
DOWNLOAD_ERROR_MSG,
DOWNLOAD_SUCCESS_MSG,
} from '@/domain/entities/download/Country';
import { SNACKBAR_SHORT_DURATION } from '@/domain/entities/snackbar/Snackbar';
import { SnackbarPosition, SnackbarStatus } from '@/domain/enums/Snackbar';
import { SubmitStatus } from '@/domain/enums/SubscribeTopic';
import DownloadCountryAccordionProps from '@/domain/props/DownloadCountryAccordionProps';
import DownloadRepository from '@/domain/repositories/DownloadRepository';
EXPORT_COUNTRY_DESCRIPTION,
} from '@/operations/download-portal/DownloadPortalConstants';
import { DownloadPortalOperations } from '@/operations/download-portal/DownloadPortalOperations';

import { SubmitButton } from '../SubmitButton/SubmitButton';
Expand Down Expand Up @@ -94,7 +94,7 @@ export default function DownloadCountryAccordion({ countries }: DownloadCountryA

return (
<div className="flex flex-col gap-4 justify-center flex-wrap pb-8">
<h6>{DESCRIPTION}</h6>
<h6>{EXPORT_COUNTRY_DESCRIPTION}</h6>

<form className="flex flex-col md:flex-row space-y-2 md:space-y-0" onSubmit={handleSubmit}>
<Autocomplete
Expand Down
12 changes: 7 additions & 5 deletions src/components/DownloadPortal/CountryReports.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import PdfPreview from '@/components/Pdf/PdfPreview';
import SearchBar from '@/components/Search/SearchBar';
import CustomTable from '@/components/Table/CustomTable';
import { useChatbot } from '@/domain/contexts/ChatbotContext';
import { useSnackbar } from '@/domain/contexts/SnackbarContext';
import { CountryCodesData } from '@/domain/entities/country/CountryCodesData';
import CountryReportsProps from '@/domain/props/CountryReportsProps';
import { PdfFile } from '@/domain/props/PdfViewerProps';
Expand All @@ -18,8 +19,8 @@ export default function CountryReports({ countryCodesData }: CountryReportsProps
const [error, setError] = useState<string | null>(null);
const [selectedCountry, setSelectedCountry] = useState<CountryCodesData | null>(null);

const chatBot = useChatbot();
const { initiateChatAboutReport } = chatBot;
const { initiateChatAboutReport } = useChatbot();
const { showSnackBar } = useSnackbar();

const toggleModal = () => setModalOpen((prev) => !prev);

Expand All @@ -34,13 +35,14 @@ export default function CountryReports({ countryCodesData }: CountryReportsProps
</div>
<CustomTable
columns={DownloadPortalOperations.getColumns()}
data={DownloadPortalOperations.formatTableData(
data={DownloadPortalOperations.formatCountryTableData(
filteredData,
setSelectedCountry,
initiateChatAboutReport,
setPdfFile,
setError,
toggleModal
toggleModal,
showSnackBar
)}
ariaLabel="Country Reports"
/>
Expand All @@ -51,7 +53,7 @@ export default function CountryReports({ countryCodesData }: CountryReportsProps
error={error}
onDownloadPdf={() => {
if (selectedCountry) {
DownloadPortalOperations.downloadPdf(selectedCountry);
DownloadPortalOperations.downloadCountryReport(selectedCountry, showSnackBar);
}
}}
/>
Expand Down
52 changes: 52 additions & 0 deletions src/components/DownloadPortal/YearInReviewReports.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use client';

import { useState } from 'react';

import { useChatbot } from '@/domain/contexts/ChatbotContext';
import { useSnackbar } from '@/domain/contexts/SnackbarContext';
import { YearInReview } from '@/domain/entities/YearInReview';
import { PdfFile } from '@/domain/props/PdfViewerProps';
import YearInReviewReportsProps from '@/domain/props/YearInReviewReportsProps';
import { DownloadPortalOperations } from '@/operations/download-portal/DownloadPortalOperations';

import PdfPreview from '../Pdf/PdfPreview';
import CustomTable from '../Table/CustomTable';

export default function YearInReviewReports({ yearInReviewReports }: YearInReviewReportsProps) {
const [isModalOpen, setModalOpen] = useState(false);
const [pdfFile, setPdfFile] = useState<PdfFile | null>(null);
const [error, setError] = useState<string | null>(null);
const [selectedReport, setSelectedReport] = useState<YearInReview | null>(null);
const { initiateChatAboutReport } = useChatbot();
const toggleModal = () => setModalOpen((prev) => !prev);
const { showSnackBar } = useSnackbar();

return (
<div>
<CustomTable
columns={DownloadPortalOperations.getColumns()}
data={DownloadPortalOperations.formatYearInReviewTableData(
yearInReviewReports,
setSelectedReport,
initiateChatAboutReport,
setPdfFile,
setError,
toggleModal,
showSnackBar
)}
ariaLabel="Year In Review Reports"
/>
<PdfPreview
isModalOpen={isModalOpen}
toggleModal={toggleModal}
pdfFile={pdfFile}
error={error}
onDownloadPdf={() => {
if (selectedReport) {
DownloadPortalOperations.downloadYearInReviewReport(selectedReport, showSnackBar);
}
}}
/>
</div>
);
}
14 changes: 7 additions & 7 deletions src/domain/contexts/ChatbotContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,13 @@ export function ChatbotProvider({ children }: { children: ReactNode }) {
};

/**
* Initiates a chat with a report based on the provided country name and report content.
* If a chat for that specific already exists, it opens that chat; otherwise, it creates a new one.
* @param countryName - The name of the country related to the report.
* Initiates a chat with a report based on the provided report name and report content.
* If a chat for that specific report already exists, it opens that chat; otherwise, it creates a new one.
* @param reportName - The name of the report.
* @param reportURL - The URL of the report to be processed.
*/
const initiateChatAboutReport = async (countryName: string, reportURL: string) => {
const reportChatIndex = chats.findIndex((chat) => chat.title === `Report ${countryName}`);
const initiateChatAboutReport = async (reportName: string, reportURL: string) => {
const reportChatIndex = chats.findIndex((chat) => chat.title === `Report ${reportName}`);
const reportChatExists = reportChatIndex !== -1;

if (reportChatExists) {
Expand All @@ -105,14 +105,14 @@ export function ChatbotProvider({ children }: { children: ReactNode }) {
const assistantMessage = {
id: crypto.randomUUID(),
content: reportText
? `Hey, how can I help you with this report about ${countryName}?`
? `Hey, how can I help you with this report about ${reportName}?`
: `Hey, unfortunately I'm currently unable to answer questions about this report. You can try it later or chat with me about other things!`,
role: SenderRole.ASSISTANT,
};

const newChat: IChat = {
id: chats.length + 1,
title: `Report ${countryName}`,
title: `Report ${reportName}`,
context: reportText,
isReportStarter: true,
messages: [assistantMessage],
Expand Down
14 changes: 0 additions & 14 deletions src/domain/entities/download/Country.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,3 @@ export interface ICountryData {
dataType: string;
metrics: IMetrics;
}

export const DESCRIPTION = 'Select a country and a date range to download its food security data.';

export const TITLE = 'Export Country Food Security Data';

export const COUNTRY_ERROR_MSG = 'Country is required';

export const DATE_RANGE_ERROR_MSG = 'Date range is required';

export const DATE_RANGE_TOO_LONG_ERROR_MSG = 'Date range must be less than 500 days';

export const DOWNLOAD_SUCCESS_MSG = 'Download successful!';

export const DOWNLOAD_ERROR_MSG = 'Download failed!';
5 changes: 5 additions & 0 deletions src/domain/props/YearInReviewReportsProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { YearInReview } from '../entities/YearInReview';

export default interface YearInReviewReportsProps {
yearInReviewReports: YearInReview[];
}
17 changes: 17 additions & 0 deletions src/operations/download-portal/DownloadPortalConstants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const EXPORT_COUNTRY_DESCRIPTION = 'Select a country and a date range to download its food security data.';

export const EXPORT_COUNTRY_DATA_TITLE = 'Export Country Food Security Data';

export const COUNTRY_ERROR_MSG = 'Country is required';

export const DATE_RANGE_ERROR_MSG = 'Date range is required';

export const DATE_RANGE_TOO_LONG_ERROR_MSG = 'Date range must be less than 500 days';

export const DOWNLOAD_SUCCESS_MSG = 'Download successful!';

export const DOWNLOAD_ERROR_MSG = 'Download failed!';

export const COUNTRY_REPORTS_TITLE = 'Country Reports';

export const YEAR_IN_REVIEW_REPORTS_TITLE = 'WFP Real Time Monitoring: Year in Review Reports';
Loading
Loading