diff --git a/components/input/MonthSelect.js b/components/input/MonthSelect.js index bb054446..a20890ad 100644 --- a/components/input/MonthSelect.js +++ b/components/input/MonthSelect.js @@ -1,5 +1,13 @@ -import { useRef, useState } from 'react'; -import { Text, Icon, CalendarMonthSelect, CalendarYearSelect, Button } from 'react-basics'; +import { useRef } from 'react'; +import { + Text, + Icon, + CalendarMonthSelect, + CalendarYearSelect, + Button, + PopupTrigger, + Popup, +} from 'react-basics'; import { startOfMonth, endOfMonth } from 'date-fns'; import Icons from 'components/icons'; import { useLocale } from 'hooks'; @@ -7,43 +15,50 @@ import { formatDate } from 'lib/date'; import { getDateLocale } from 'lib/lang'; import styles from './MonthSelect.module.css'; -const MONTH = 'month'; -const YEAR = 'year'; - export function MonthSelect({ date = new Date(), onChange }) { const { locale } = useLocale(); - const [select, setSelect] = useState(null); const month = formatDate(date, 'MMMM', locale); const year = date.getFullYear(); const ref = useRef(); - const handleSelect = value => { - setSelect(state => (state !== value ? value : null)); - }; - const handleChange = date => { onChange(`range:${startOfMonth(date).getTime()}:${endOfMonth(date).getTime()}`); - setSelect(null); }; return ( <>
- - + + + + + + + + + + + +
- {select === MONTH && ( - - )} - {select === YEAR && ( - - )} ); } diff --git a/components/input/MonthSelect.module.css b/components/input/MonthSelect.module.css index 04cf575c..3b13bcc1 100644 --- a/components/input/MonthSelect.module.css +++ b/components/input/MonthSelect.module.css @@ -2,6 +2,8 @@ display: flex; align-items: center; justify-content: center; + border: 1px solid var(--base400); + border-radius: var(--border-radius); } .input { @@ -10,3 +12,11 @@ gap: 10px; cursor: pointer; } + +.popup { + border: 1px solid var(--base400); + background: var(--base50); + border-radius: var(--border-radius); + padding: 20px; + margin-top: 5px; +} diff --git a/components/pages/reports/PopupForm.js b/components/pages/reports/PopupForm.js index 0f0ead36..0e825a26 100644 --- a/components/pages/reports/PopupForm.js +++ b/components/pages/reports/PopupForm.js @@ -1,29 +1,11 @@ -import { createPortal } from 'react-dom'; -import { useDocumentClick, useKeyDown } from 'react-basics'; import classNames from 'classnames'; import styles from './PopupForm.module.css'; -export function PopupForm({ element, className, children, onClose }) { - const { right, top } = element.getBoundingClientRect(); - const style = { position: 'absolute', left: right, top }; - - useKeyDown('Escape', onClose); - - useDocumentClick(e => { - if (e.target !== element && !element?.parentElement?.contains(e.target)) { - onClose(); - } - }); - - const handleClick = e => { - e.stopPropagation(); - }; - - return createPortal( -
+export function PopupForm({ className, style, children }) { + return ( +
{children} -
, - document.body, +
); } diff --git a/components/pages/reports/PopupForm.module.css b/components/pages/reports/PopupForm.module.css index 4daf199a..94d98b38 100644 --- a/components/pages/reports/PopupForm.module.css +++ b/components/pages/reports/PopupForm.module.css @@ -3,8 +3,8 @@ background: var(--base50); min-width: 300px; padding: 20px; - margin-left: 30px; border: 1px solid var(--base400); border-radius: var(--border-radius); box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.1); + z-index: 1000; } diff --git a/components/pages/reports/insights/InsightsParameters.js b/components/pages/reports/insights/InsightsParameters.js index 6de4b838..9f3571e6 100644 --- a/components/pages/reports/insights/InsightsParameters.js +++ b/components/pages/reports/insights/InsightsParameters.js @@ -80,10 +80,10 @@ export function InsightsParameters() { - - {(close, element) => { + + {close => { return ( - + {id === 'fields' && ( }> handleRemove(id, index)}> - {({ name, filter, value, label }) => { + {({ name, filter, value }) => { return (
{id === 'fields' && ( diff --git a/components/pages/reports/insights/InsightsParameters.module.css b/components/pages/reports/insights/InsightsParameters.module.css index 06b62414..c84f8a9e 100644 --- a/components/pages/reports/insights/InsightsParameters.module.css +++ b/components/pages/reports/insights/InsightsParameters.module.css @@ -10,3 +10,8 @@ .op { font-weight: bold; } + +.popup { + margin-top: -10px; + margin-left: 30px; +} diff --git a/components/pages/reports/retention/RetentionParameters.js b/components/pages/reports/retention/RetentionParameters.js index 1eee6bf2..d98608ae 100644 --- a/components/pages/reports/retention/RetentionParameters.js +++ b/components/pages/reports/retention/RetentionParameters.js @@ -31,7 +31,7 @@ export function RetentionParameters() { return (
- + diff --git a/components/pages/reports/retention/RetentionReport.js b/components/pages/reports/retention/RetentionReport.js index 63eea44c..a9aaeb3e 100644 --- a/components/pages/reports/retention/RetentionReport.js +++ b/components/pages/reports/retention/RetentionReport.js @@ -6,10 +6,16 @@ import ReportMenu from '../ReportMenu'; import ReportBody from '../ReportBody'; import Magnet from 'assets/magnet.svg'; import { REPORT_TYPES } from 'lib/constants'; +import { parseDateRange } from 'lib/date'; +import { endOfMonth, startOfMonth } from 'date-fns'; const defaultParameters = { type: REPORT_TYPES.retention, - parameters: {}, + parameters: { + dateRange: parseDateRange( + `range:${startOfMonth(new Date()).getTime()}:${endOfMonth(new Date()).getTime()}`, + ), + }, }; export default function RetentionReport({ reportId }) { diff --git a/components/pages/reports/retention/RetentionTable.js b/components/pages/reports/retention/RetentionTable.js index f7d8c4bb..df0b0f99 100644 --- a/components/pages/reports/retention/RetentionTable.js +++ b/components/pages/reports/retention/RetentionTable.js @@ -1,5 +1,4 @@ import { useContext } from 'react'; -import { GridTable, GridColumn } from 'react-basics'; import classNames from 'classnames'; import { ReportContext } from '../Report'; import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; @@ -16,14 +15,26 @@ export function RetentionTable() { return ; } - const rows = data.reduce((arr, { date, visitors }) => { - if (!arr.find(a => a.date === date)) { - return arr.concat({ date, visitors }); + const days = [1, 2, 3, 4, 5, 6, 7, 14, 21, 28]; + + const rows = data.reduce((arr, row) => { + const { date, visitors, day } = row; + if (day === 0) { + return arr.concat({ + date, + visitors, + records: days + .reduce((arr, day) => { + arr[day] = data.find(x => x.date === date && x.day === day); + return arr; + }, []) + .filter(n => n), + }); } return arr; }, []); - const days = [1, 2, 3, 4, 5, 6, 7, 14, 21, 30]; + const totalDays = rows.length; return ( <> @@ -37,15 +48,22 @@ export function RetentionTable() {
))} - {rows.map(({ date, visitors }, i) => { + {rows.map(({ date, visitors, records }, rowIndex) => { return ( -
+
{formatDate(`${date} 00:00:00`, 'PP')}
{visitors}
- {days.map((n, day) => { + {days.map(day => { + if (totalDays - rowIndex < day) { + return null; + } + const percentage = records[day]?.percentage; return ( -
- {data.find(row => row.date === date && row.day === day)?.percentage.toFixed(2)} +
+ {percentage ? `${percentage.toFixed(2)}%` : ''}
); })} @@ -53,31 +71,8 @@ export function RetentionTable() { ); })}
- ); } -function DataTable({ data }) { - return ( - - - {row => row.date} - - - {row => row.day} - - - {row => row.visitors} - - - {row => row.returnVisitors} - - - {row => row.percentage} - - - ); -} - export default RetentionTable; diff --git a/components/pages/reports/retention/RetentionTable.module.css b/components/pages/reports/retention/RetentionTable.module.css index 79cbbc5f..bfe3ac1c 100644 --- a/components/pages/reports/retention/RetentionTable.module.css +++ b/components/pages/reports/retention/RetentionTable.module.css @@ -20,7 +20,7 @@ justify-content: center; width: 60px; height: 60px; - background: var(--blue100); + background: var(--blue200); border-radius: var(--border-radius); } @@ -46,3 +46,7 @@ font-size: var(--font-size-sm); font-weight: 400; } + +.empty { + background: var(--blue100); +} diff --git a/package.json b/package.json index 46ad4d2d..9d2de093 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "node-fetch": "^3.2.8", "npm-run-all": "^4.1.5", "react": "^18.2.0", - "react-basics": "^0.94.0", + "react-basics": "^0.96.0", "react-beautiful-dnd": "^13.1.0", "react-dom": "^18.2.0", "react-error-boundary": "^4.0.4", diff --git a/yarn.lock b/yarn.lock index e67cc413..350e483f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7557,10 +7557,10 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-basics@^0.94.0: - version "0.94.0" - resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.94.0.tgz#c15698148b959f40c6b451088f36f5735eb82815" - integrity sha512-OlUHWrGRctRGEm+yL9iWSC9HRnxZhlm3enP2iCKytVmt7LvaPtsK4RtZ27qp4irNvuzg79aqF+h5IFnG+Vi7WA== +react-basics@^0.96.0: + version "0.96.0" + resolved "https://registry.yarnpkg.com/react-basics/-/react-basics-0.96.0.tgz#e5e72201abdccdda94b952ef605163ca11772d8f" + integrity sha512-WNAxP+0xBtUNgEXrL8aW6UQMmD6WoX9My0VW6uq+Q262DOPTU3zPtWl+9vvES4pF3tPJCFvmFAlK/Alw9+XKVQ== dependencies: classnames "^2.3.1" date-fns "^2.29.3"