Skip to content

Commit

Permalink
Merge pull request #7372 from uktrade/bugfix/export-win-dates
Browse files Browse the repository at this point in the history
Fix export win dates
  • Loading branch information
paulgain authored Dec 9, 2024
2 parents d5fdc0b + dd4e853 commit b77df74
Show file tree
Hide file tree
Showing 11 changed files with 429 additions and 129 deletions.
15 changes: 10 additions & 5 deletions src/client/modules/ExportWins/Status/WinsConfirmedList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import React from 'react'

import ExportWinsResource from '../../../components/Resource/ExportWins'
import { currencyGBP } from '../../../utils/number-utils'
import { formatMediumDateParsed } from '../../../utils/date'
import {
formatDate,
DATE_FORMAT_MEDIUM,
DATE_FORMAT_MONTH_ABBR_YEAR,
} from '../../../utils/date-utils'
import { CollectionItem } from '../../../components'
import { sumExportValues, createRoleTags } from './utils'
import { SORT_OPTIONS, WIN_STATUS } from './constants'
Expand Down Expand Up @@ -35,13 +39,14 @@ export const WinsConfirmedList = ({ exportWins = [], currentAdviserId }) => {
},
{
label: 'Date won:',
value: formatMediumDateParsed(item.date),
value: formatDate(item.date, DATE_FORMAT_MONTH_ABBR_YEAR), // Dec 2024
},
{
label: 'Date responded:',
value: item.customer_response.responded_on
? formatMediumDateParsed(item.customer_response?.responded_on)
: '',
value: formatDate(
item.customer_response?.responded_on,
DATE_FORMAT_MEDIUM // 4 Dec 2024
),
},
]}
/>
Expand Down
20 changes: 13 additions & 7 deletions src/client/modules/ExportWins/Status/WinsPendingList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import Link from '@govuk-react/link'
import ExportWinsResource from '../../../components/Resource/ExportWins'
import { currencyGBP } from '../../../utils/number-utils'
import {
formatMediumDate,
formatMediumDateTimeWithoutParsing,
} from '../../../utils/date'
formatDate,
DATE_FORMAT_MEDIUM,
DATE_FORMAT_MONTH_ABBR_YEAR,
DATE_FORMAT_MEDIUM_WITH_TIME,
} from '../../../utils/date-utils'

import { CollectionItem } from '../../../components'
import { sumExportValues, createRoleTags } from './utils'
import { SORT_OPTIONS, WIN_STATUS } from './constants'
Expand Down Expand Up @@ -48,18 +51,21 @@ export const WinsPendingList = ({ exportWins = [], currentAdviserId }) => {
label: 'Total value:',
value: currencyGBP(sumExportValues(item)),
},
{ label: 'Date won:', value: formatMediumDate(item.date) },
{
label: 'Date won:',
value: formatDate(item.date, DATE_FORMAT_MONTH_ABBR_YEAR), // Dec 2024
},
{
label: 'Date modified:',
value: formatMediumDate(item.modified_on),
value: formatDate(item.modified_on, DATE_FORMAT_MEDIUM), // 4 Dec 2024
},
{
label: 'First sent:',
value: formatMediumDateTimeWithoutParsing(item.first_sent),
value: formatDate(item.first_sent, DATE_FORMAT_MEDIUM_WITH_TIME), // 4 Dec 2024, 3:30PM
},
{
label: 'Last sent:',
value: formatMediumDateTimeWithoutParsing(item.last_sent),
value: formatDate(item.last_sent, DATE_FORMAT_MEDIUM_WITH_TIME), // 4 Dec 2024, 3:30PM
},
]}
/>
Expand Down
13 changes: 10 additions & 3 deletions src/client/modules/ExportWins/Status/WinsRejectedList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import React from 'react'

import ExportWinsResource from '../../../components/Resource/ExportWins'
import { currencyGBP } from '../../../utils/number-utils'
import { formatMediumDate } from '../../../utils/date'
import {
formatDate,
DATE_FORMAT_MEDIUM,
DATE_FORMAT_MONTH_ABBR_YEAR,
} from '../../../utils/date-utils'
import { CollectionItem } from '../../../components'
import { sumExportValues, createRoleTags } from './utils'
import { SORT_OPTIONS, WIN_STATUS } from './constants'
Expand Down Expand Up @@ -33,10 +37,13 @@ export const WinsRejectedList = ({ exportWins, currentAdviserId }) => {
label: 'Total value:',
value: currencyGBP(sumExportValues(item)),
},
{ label: 'Date won:', value: formatMediumDate(item.date) },
{
label: 'Date won:',
value: formatDate(item.date, DATE_FORMAT_MONTH_ABBR_YEAR), // Dec 2024
},
{
label: 'Date modified:',
value: formatMediumDate(item.modified_on),
value: formatDate(item.modified_on, DATE_FORMAT_MEDIUM), // 4 Dec 2024
},
]}
/>
Expand Down
72 changes: 72 additions & 0 deletions src/client/utils/__test__/date-utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {
formatDate,
DATE_FORMAT_FULL,
DATE_FORMAT_FULL_DAY,
DATE_FORMAT_COMPACT,
DATE_FORMAT_ISO,
DATE_FORMAT_MEDIUM,
DATE_FORMAT_MEDIUM_WITH_TIME,
DATE_FORMAT_YEAR_MONTH,
DATE_FORMAT_MONTH_YEAR,
DATE_FORMAT_MONTH_ABBR_YEAR,
DATE_FORMAT_DAY_MONTH,
DATE_FORMAT_INTERACTION_TIMESTAMP,
} from '../date-utils'

describe('formatDate', () => {
const date = '2024-12-04'
const time = 'T10:41:45.425717Z'
const dateAndTime = `${date}${time}`

it("should render '04 Dec 2024' (default format)", () => {
expect(formatDate(date)).to.equal('04 Dec 2024') // the default
})

it("should render '04 Dec 2024' (DATE_FORMAT_COMPACT)", () => {
expect(formatDate(date, DATE_FORMAT_COMPACT)).to.equal('04 Dec 2024')
})

it("should render '4 Dec 2024' (DATE_FORMAT_MEDIUM)", () => {
expect(formatDate(dateAndTime, DATE_FORMAT_MEDIUM)).to.equal('4 Dec 2024')
})

it("should render '4 Dec 2024, 10:41am' (DATE_FORMAT_MEDIUM_WITH_TIME)", () => {
expect(formatDate(dateAndTime, DATE_FORMAT_MEDIUM_WITH_TIME)).to.equal(
'4 Dec 2024, 10:41am'
)
})

it("should render '4 December 2024' (DATE_FORMAT_FULL)", () => {
expect(formatDate(date, DATE_FORMAT_FULL)).to.equal('4 December 2024')
})

it("should render 'Wed, 04 Dec 2024' (DATE_FORMAT_FULL_DAY)", () => {
expect(formatDate(date, DATE_FORMAT_FULL_DAY)).to.equal('Wed, 04 Dec 2024')
})

it("should render '2024-12-04' (DATE_FORMAT_ISO)", () => {
expect(formatDate(date, DATE_FORMAT_ISO)).to.equal('2024-12-04')
})

it("should render '2024-12' (DATE_FORMAT_YEAR_MONTH)", () => {
expect(formatDate(date, DATE_FORMAT_YEAR_MONTH)).to.equal('2024-12')
})

it("should render 'December 2024' (DATE_FORMAT_MONTH_YEAR)", () => {
expect(formatDate(date, DATE_FORMAT_MONTH_YEAR)).to.equal('December 2024')
})

it("should render 'Dec 2024' (DATE_FORMAT_MONTH_ABBR_YEAR)", () => {
expect(formatDate(date, DATE_FORMAT_MONTH_ABBR_YEAR)).to.equal('Dec 2024')
})

it("should render '04 Dec' (DATE_FORMAT_DAY_MONTH)", () => {
expect(formatDate(date, DATE_FORMAT_DAY_MONTH)).to.equal('04 Dec')
})

it("should render '2024-12-4' (DATE_FORMAT_INTERACTION_TIMESTAMP)", () => {
expect(formatDate(date, DATE_FORMAT_INTERACTION_TIMESTAMP)).to.equal(
'2024-12-4'
)
})
})
120 changes: 120 additions & 0 deletions src/client/utils/date-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const { format, parseISO } = require('date-fns')

/**
* Full date format with day and full month name.
* Example: 4 December 2024
*/
const DATE_FORMAT_FULL = 'd MMMM yyyy'

/**
* Full date format including the weekday.
* Example: Wed, 04 Dec 2024
*/
const DATE_FORMAT_FULL_DAY = 'E, dd MMM yyyy'

/**
* Compact date format with two-digit day and abbreviated month name.
* Example: 04 Dec 2024
*/
const DATE_FORMAT_COMPACT = 'dd MMM yyyy'

/**
* ISO standard date format.
* Example: 2024-12-04
*/
const DATE_FORMAT_ISO = 'yyyy-MM-dd'

/**
* Medium date format with single-digit day and abbreviated month name.
* Example: 4 Dec 2024
*/
const DATE_FORMAT_MEDIUM = 'd MMM yyyy'

/**
* Medium date format with time included in 12-hour format.
* Example: 4 Dec 2024, 3:30PM
*/
const DATE_FORMAT_MEDIUM_WITH_TIME = 'd MMM yyyy, h:mmaaa'

/**
* Year and month format for compact representations.
* Example: 2024-12
*/
const DATE_FORMAT_YEAR_MONTH = 'yyyy-MM'

/**
* Month and year format with full month name.
* Example: December 2024
*/
const DATE_FORMAT_MONTH_YEAR = 'MMMM yyyy'

/**
* Abbreviated month and year format.
* Example: Dec 2024
*/
const DATE_FORMAT_MONTH_ABBR_YEAR = 'MMM yyyy'

/**
* Day and month format with abbreviated month name.
* Example: 04 Dec
*/
const DATE_FORMAT_DAY_MONTH = 'dd MMM'

/**
* Interaction timestamp format with single-digit day and month.
* Example: 2024-12-4
*/
const DATE_FORMAT_INTERACTION_TIMESTAMP = 'y-MM-d'

/**
* Formats a given date string into a specified format using `date-fns`.
*
* @param {string} dateISO - The date string in ISO format (e.g., '2024-12-04').
* @param {string} [dateISOFormat=DATE_FORMAT_COMPACT] - The format to use for formatting the date.
* Available format constants include:
* - `DATE_FORMAT_FULL`: Full date with day and full month name (e.g., '4 December 2024').
* - `DATE_FORMAT_FULL_DAY`: Full date with weekday included (e.g., 'Wed, 04 Dec 2024').
* - `DATE_FORMAT_COMPACT`: Compact date with abbreviated month name (e.g., '04 Dec 2024').
* - `DATE_FORMAT_ISO`: ISO standard format (e.g., '2024-12-04').
* - `DATE_FORMAT_MEDIUM`: Medium date format with single-digit day (e.g., '4 Dec 2024').
* - `DATE_FORMAT_MEDIUM_WITH_TIME`: Medium date with 12-hour time (e.g., '4 Dec 2024, 3:30PM').
* - `DATE_FORMAT_YEAR_MONTH`: Year and month format (e.g., '2024-12').
* - `DATE_FORMAT_MONTH_YEAR`: Full month and year (e.g., 'December 2024').
* - `DATE_FORMAT_MONTH_ABBR_YEAR`: Abbreviated month and year (e.g., 'Dec 2024').
* - `DATE_FORMAT_DAY_MONTH`: Day and abbreviated month (e.g., '04 Dec').
* - `DATE_FORMAT_INTERACTION_TIMESTAMP`: Interaction timestamp format (e.g., '2024-12-4').
* @returns {string} - The formatted date string.
*
* @example
* // Format a date to the default compact format
* formatDate('2024-12-04')
* // Returns: '04 Dec 2024'
*
* @example
* // Format a date to a full format
* formatDate('2024-12-04', DATE_FORMAT_FULL)
* // Returns: '4 December 2024'
*
* @example
* // Format a date with abbreviated month and year
* formatDate('2024-12-04', DATE_FORMAT_MONTH_ABBR_YEAR)
* // Returns: 'Dec 2024'
*/
function formatDate(dateISO, dateISOFormat = DATE_FORMAT_COMPACT) {
return format(parseISO(dateISO), dateISOFormat)
}

module.exports = {
DATE_FORMAT_FULL,
DATE_FORMAT_FULL_DAY,
DATE_FORMAT_COMPACT,
DATE_FORMAT_ISO,
DATE_FORMAT_MEDIUM,
DATE_FORMAT_MEDIUM_WITH_TIME,
DATE_FORMAT_YEAR_MONTH,
DATE_FORMAT_MONTH_YEAR,
DATE_FORMAT_MONTH_ABBR_YEAR,
DATE_FORMAT_DAY_MONTH,
DATE_FORMAT_INTERACTION_TIMESTAMP,
formatDate,
}
50 changes: 20 additions & 30 deletions test/component/cypress/specs/ExportWins/WinsConfirmedList.cy.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,14 @@ import { WinsConfirmedList } from '../../../../../src/client/modules/ExportWins/
import { sumExportValues } from '../../../../../src/client/modules/ExportWins/Status/utils'
import { exportWinsFaker } from '../../../../functional/cypress/fakers/export-wins'
import { currencyGBP } from '../../../../../src/client/utils/number-utils'
import { formatDate } from '../../../../../src/client/utils/date-utils'
import { exportWinsData } from './export-wins-data'
import { createTestProvider } from '../provider'
import urls from '../../../../../src/lib/urls'

describe('WinsConfirmedList', () => {
const exportWin = {
id: '111',
company: {
id: '222',
name: 'Foo Ltd',
},
name_of_export: 'Rolls Reese',
company_contacts: [
{
name: 'David Test',
id: '333',
},
],
country: {
name: 'USA',
},
date: '2023-05-01',
customer_response: {
responded_on: '2024-04-18T12:15:49.361611Z',
},
total_expected_export_value: 1000,
total_expected_non_export_value: 2000,
total_expected_odi_value: 3000,
}

it('should render a list of confirmed export wins', () => {
const exportWin = exportWinsFaker()
const exportWinsList = [exportWin, exportWinsFaker(), exportWinsFaker()]

const Provider = createTestProvider({
Expand All @@ -57,7 +34,10 @@ describe('WinsConfirmedList', () => {

cy.get('@firstItem').within(() => {
cy.get('h3 a')
.should('have.text', 'Rolls Reese to USA')
.should(
'have.text',
`${exportWin.name_of_export} to ${exportWin.country.name}`
)
.and(
'have.attr',
'href',
Expand All @@ -68,7 +48,7 @@ describe('WinsConfirmedList', () => {
)

cy.get('h4 a')
.should('have.text', 'Foo Ltd')
.should('have.text', exportWin.company.name)
.and(
'have.attr',
'href',
Expand All @@ -77,7 +57,12 @@ describe('WinsConfirmedList', () => {

const items = '[data-test="metadata-item"]'
cy.get(items).should('have.length', 4)
cy.get(items).eq(0).should('have.text', 'Contact name: David Test')
cy.get(items)
.eq(0)
.should(
'have.text',
`Contact name: ${exportWin.company_contacts[0].name}`
)
cy.get(items)
.eq(1)
.should(
Expand All @@ -92,8 +77,13 @@ describe('WinsConfirmedList', () => {
)
)}`
)
cy.get(items).eq(2).should('have.text', 'Date won: 1 May 2023')
cy.get(items).eq(3).should('have.text', 'Date responded: 18 Apr 2024')
cy.get(items).eq(2).should('have.text', 'Date won: May 2023')
cy.get(items)
.eq(3)
.should(
'have.text',
`Date responded: ${formatDate(exportWin.customer_response.responded_on)}`
)
})
})

Expand Down
Loading

0 comments on commit b77df74

Please sign in to comment.