Added AnimatedDiv component.

This commit is contained in:
Mike Cao 2025-02-14 17:16:09 -08:00
parent 2978bf3c6f
commit a8a1ccce18
26 changed files with 83 additions and 80 deletions

View file

@ -1,5 +1,5 @@
import { Metadata } from 'next'; import { Metadata } from 'next';
import ConsolePage from '../ConsolePage'; import { ConsolePage } from '../ConsolePage';
async function getEnabled() { async function getEnabled() {
return !!process.env.ENABLE_TEST_CONSOLE; return !!process.env.ENABLE_TEST_CONSOLE;

View file

@ -2,9 +2,9 @@ import { useFields, useMessages } from '@/components/hooks';
import { Icons } from '@/components/icons'; import { Icons } from '@/components/icons';
import { useContext } from 'react'; import { useContext } from 'react';
import { Button, FormRow, Icon, Popup, PopupTrigger } from 'react-basics'; import { Button, FormRow, Icon, Popup, PopupTrigger } from 'react-basics';
import FieldSelectForm from '../[reportId]/FieldSelectForm'; import { FieldSelectForm } from '../[reportId]/FieldSelectForm';
import ParameterList from '../[reportId]/ParameterList'; import { ParameterList } from '../[reportId]/ParameterList';
import PopupForm from '../[reportId]/PopupForm'; import { PopupForm } from '../[reportId]/PopupForm';
import { ReportContext } from './Report'; import { ReportContext } from './Report';
export function FieldParameters() { export function FieldParameters() {

View file

@ -2,11 +2,11 @@ import { useContext } from 'react';
import { useMessages, useFormat, useFilters, useFields } from '@/components/hooks'; import { useMessages, useFormat, useFilters, useFields } from '@/components/hooks';
import { Icons } from '@/components/icons'; import { Icons } from '@/components/icons';
import { Button, FormRow, Icon, Popup, PopupTrigger } from 'react-basics'; import { Button, FormRow, Icon, Popup, PopupTrigger } from 'react-basics';
import FilterSelectForm from '../[reportId]/FilterSelectForm'; import { FilterSelectForm } from '../[reportId]/FilterSelectForm';
import ParameterList from '../[reportId]/ParameterList'; import { ParameterList } from '../[reportId]/ParameterList';
import PopupForm from '../[reportId]/PopupForm'; import { PopupForm } from '../[reportId]/PopupForm';
import { ReportContext } from './Report'; import { ReportContext } from './Report';
import FieldFilterEditForm from '../[reportId]/FieldFilterEditForm'; import { FieldFilterEditForm } from '../[reportId]/FieldFilterEditForm';
import { isSearchOperator } from '@/lib/params'; import { isSearchOperator } from '@/lib/params';
import styles from './FilterParameters.module.css'; import styles from './FilterParameters.module.css';

View file

@ -1,13 +1,13 @@
'use client'; 'use client';
import { useReport } from '@/components/hooks'; import { useReport } from '@/components/hooks';
import EventDataReport from '../event-data/EventDataReport'; import { EventDataReport } from '../event-data/EventDataReport';
import FunnelReport from '../funnel/FunnelReport'; import { FunnelReport } from '../funnel/FunnelReport';
import GoalReport from '../goals/GoalsReport'; import { GoalsReport } from '../goals/GoalsReport';
import InsightsReport from '../insights/InsightsReport'; import { InsightsReport } from '../insights/InsightsReport';
import JourneyReport from '../journey/JourneyReport'; import { JourneyReport } from '../journey/JourneyReport';
import RetentionReport from '../retention/RetentionReport'; import { RetentionReport } from '../retention/RetentionReport';
import UTMReport from '../utm/UTMReport'; import { UTMReport } from '../utm/UTMReport';
import RevenueReport from '../revenue/RevenueReport'; import { RevenueReport } from '../revenue/RevenueReport';
const reports = { const reports = {
funnel: FunnelReport, funnel: FunnelReport,
@ -15,7 +15,7 @@ const reports = {
insights: InsightsReport, insights: InsightsReport,
retention: RetentionReport, retention: RetentionReport,
utm: UTMReport, utm: UTMReport,
goals: GoalReport, goals: GoalsReport,
journey: JourneyReport, journey: JourneyReport,
revenue: RevenueReport, revenue: RevenueReport,
}; };

View file

@ -5,9 +5,9 @@ import { Icons } from '@/components/icons';
import { useApi, useMessages } from '@/components/hooks'; import { useApi, useMessages } from '@/components/hooks';
import { DATA_TYPES, REPORT_PARAMETERS } from '@/lib/constants'; import { DATA_TYPES, REPORT_PARAMETERS } from '@/lib/constants';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
import FieldAddForm from '../[reportId]/FieldAddForm'; import { FieldAddForm } from '../[reportId]/FieldAddForm';
import ParameterList from '../[reportId]/ParameterList'; import { ParameterList } from '../[reportId]/ParameterList';
import BaseParameters from '../[reportId]/BaseParameters'; import { BaseParameters } from '../[reportId]/BaseParameters';
import styles from './EventDataParameters.module.css'; import styles from './EventDataParameters.module.css';
function useFields(websiteId, startDate, endDate) { function useFields(websiteId, startDate, endDate) {

View file

@ -1,7 +1,7 @@
import Report from '../[reportId]/Report'; import { Report } from '../[reportId]/Report';
import ReportHeader from '../[reportId]/ReportHeader'; import { ReportHeader } from '../[reportId]/ReportHeader';
import ReportMenu from '../[reportId]/ReportMenu'; import { ReportMenu } from '../[reportId]/ReportMenu';
import ReportBody from '../[reportId]/ReportBody'; import { ReportBody } from '../[reportId]/ReportBody';
import { EventDataParameters } from './EventDataParameters'; import { EventDataParameters } from './EventDataParameters';
import { EventDataTable } from './EventDataTable'; import { EventDataTable } from './EventDataTable';
import Nodes from '@/assets/nodes.svg'; import Nodes from '@/assets/nodes.svg';

View file

@ -15,9 +15,9 @@ import {
import { Icons } from '@/components/icons'; import { Icons } from '@/components/icons';
import { FunnelStepAddForm } from './FunnelStepAddForm'; import { FunnelStepAddForm } from './FunnelStepAddForm';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
import BaseParameters from '../[reportId]/BaseParameters'; import { BaseParameters } from '../[reportId]/BaseParameters';
import ParameterList from '../[reportId]/ParameterList'; import { ParameterList } from '../[reportId]/ParameterList';
import PopupForm from '../[reportId]/PopupForm'; import { PopupForm } from '../[reportId]/PopupForm';
import styles from './FunnelParameters.module.css'; import styles from './FunnelParameters.module.css';
export function FunnelParameters() { export function FunnelParameters() {

View file

@ -1,9 +1,9 @@
import { FunnelChart } from './FunnelChart'; import { FunnelChart } from './FunnelChart';
import { FunnelParameters } from './FunnelParameters'; import { FunnelParameters } from './FunnelParameters';
import Report from '../[reportId]/Report'; import { Report } from '../[reportId]/Report';
import ReportHeader from '../[reportId]/ReportHeader'; import { ReportHeader } from '../[reportId]/ReportHeader';
import ReportMenu from '../[reportId]/ReportMenu'; import { ReportMenu } from '../[reportId]/ReportMenu';
import ReportBody from '../[reportId]/ReportBody'; import { ReportBody } from '../[reportId]/ReportBody';
import Funnel from '@/assets/funnel.svg'; import Funnel from '@/assets/funnel.svg';
import { REPORT_TYPES } from '@/lib/constants'; import { REPORT_TYPES } from '@/lib/constants';

View file

@ -13,9 +13,9 @@ import {
PopupTrigger, PopupTrigger,
SubmitButton, SubmitButton,
} from 'react-basics'; } from 'react-basics';
import BaseParameters from '../[reportId]/BaseParameters'; import { BaseParameters } from '../[reportId]/BaseParameters';
import ParameterList from '../[reportId]/ParameterList'; import { ParameterList } from '../[reportId]/ParameterList';
import PopupForm from '../[reportId]/PopupForm'; import { PopupForm } from '../[reportId]/PopupForm';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
import { GoalsAddForm } from './GoalsAddForm'; import { GoalsAddForm } from './GoalsAddForm';
import styles from './GoalsParameters.module.css'; import styles from './GoalsParameters.module.css';

View file

@ -1,9 +1,9 @@
import { GoalsChart } from './GoalsChart'; import { GoalsChart } from './GoalsChart';
import { GoalsParameters } from './GoalsParameters'; import { GoalsParameters } from './GoalsParameters';
import Report from '../[reportId]/Report'; import { Report } from '../[reportId]/Report';
import ReportHeader from '../[reportId]/ReportHeader'; import { ReportHeader } from '../[reportId]/ReportHeader';
import ReportMenu from '../[reportId]/ReportMenu'; import { ReportMenu } from '../[reportId]/ReportMenu';
import ReportBody from '../[reportId]/ReportBody'; import { ReportBody } from '../[reportId]/ReportBody';
import Target from '@/assets/target.svg'; import Target from '@/assets/target.svg';
import { REPORT_TYPES } from '@/lib/constants'; import { REPORT_TYPES } from '@/lib/constants';

View file

@ -1,10 +1,10 @@
import { useMessages } from '@/components/hooks'; import { useMessages } from '@/components/hooks';
import { useContext } from 'react'; import { useContext } from 'react';
import { Form, FormButtons, SubmitButton } from 'react-basics'; import { Form, FormButtons, SubmitButton } from 'react-basics';
import BaseParameters from '../[reportId]/BaseParameters'; import { BaseParameters } from '../[reportId]/BaseParameters';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
import FieldParameters from '../[reportId]/FieldParameters'; import { FieldParameters } from '../[reportId]/FieldParameters';
import FilterParameters from '../[reportId]/FilterParameters'; import { FilterParameters } from '../[reportId]/FilterParameters';
export function InsightsParameters() { export function InsightsParameters() {
const { report, runReport, isRunning } = useContext(ReportContext); const { report, runReport, isRunning } = useContext(ReportContext);

View file

@ -1,7 +1,7 @@
import Report from '../[reportId]/Report'; import { Report } from '../[reportId]/Report';
import ReportHeader from '../[reportId]/ReportHeader'; import { ReportHeader } from '../[reportId]/ReportHeader';
import ReportMenu from '../[reportId]/ReportMenu'; import { ReportMenu } from '../[reportId]/ReportMenu';
import ReportBody from '../[reportId]/ReportBody'; import { ReportBody } from '../[reportId]/ReportBody';
import { InsightsParameters } from './InsightsParameters'; import { InsightsParameters } from './InsightsParameters';
import { InsightsTable } from './InsightsTable'; import { InsightsTable } from './InsightsTable';
import Lightbulb from '@/assets/lightbulb.svg'; import Lightbulb from '@/assets/lightbulb.svg';

View file

@ -11,7 +11,7 @@ import {
TextField, TextField,
} from 'react-basics'; } from 'react-basics';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
import BaseParameters from '../[reportId]/BaseParameters'; import { BaseParameters } from '../[reportId]/BaseParameters';
export function JourneyParameters() { export function JourneyParameters() {
const { report, runReport, isRunning } = useContext(ReportContext); const { report, runReport, isRunning } = useContext(ReportContext);

View file

@ -1,8 +1,8 @@
'use client'; 'use client';
import Report from '../[reportId]/Report'; import { Report } from '../[reportId]/Report';
import ReportHeader from '../[reportId]/ReportHeader'; import { ReportHeader } from '../[reportId]/ReportHeader';
import ReportMenu from '../[reportId]/ReportMenu'; import { ReportMenu } from '../[reportId]/ReportMenu';
import ReportBody from '../[reportId]/ReportBody'; import { ReportBody } from '../[reportId]/ReportBody';
import { JourneyParameters } from './JourneyParameters'; import { JourneyParameters } from './JourneyParameters';
import { JourneyView } from './JourneyView'; import { JourneyView } from './JourneyView';
import Path from '@/assets/path.svg'; import Path from '@/assets/path.svg';

View file

@ -3,7 +3,7 @@ import { useMessages } from '@/components/hooks';
import { Form, FormButtons, FormRow, SubmitButton } from 'react-basics'; import { Form, FormButtons, FormRow, SubmitButton } from 'react-basics';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
import { MonthSelect } from '@/components/input/MonthSelect'; import { MonthSelect } from '@/components/input/MonthSelect';
import BaseParameters from '../[reportId]/BaseParameters'; import { BaseParameters } from '../[reportId]/BaseParameters';
import { parseDateRange } from '@/lib/date'; import { parseDateRange } from '@/lib/date';
export function RetentionParameters() { export function RetentionParameters() {

View file

@ -1,9 +1,9 @@
import { RetentionTable } from './RetentionTable'; import { RetentionTable } from './RetentionTable';
import { RetentionParameters } from './RetentionParameters'; import { RetentionParameters } from './RetentionParameters';
import Report from '../[reportId]/Report'; import { Report } from '../[reportId]/Report';
import ReportHeader from '../[reportId]/ReportHeader'; import { ReportHeader } from '../[reportId]/ReportHeader';
import ReportMenu from '../[reportId]/ReportMenu'; import { ReportMenu } from '../[reportId]/ReportMenu';
import ReportBody from '../[reportId]/ReportBody'; import { ReportBody } from '../[reportId]/ReportBody';
import Magnet from '@/assets/magnet.svg'; import Magnet from '@/assets/magnet.svg';
import { REPORT_TYPES } from '@/lib/constants'; import { REPORT_TYPES } from '@/lib/constants';
import { parseDateRange } from '@/lib/date'; import { parseDateRange } from '@/lib/date';

View file

@ -2,7 +2,7 @@ import { useMessages } from '@/components/hooks';
import { useRevenueValues } from '@/components/hooks/queries/useRevenueValues'; import { useRevenueValues } from '@/components/hooks/queries/useRevenueValues';
import { useContext } from 'react'; import { useContext } from 'react';
import { Dropdown, Form, FormButtons, FormInput, FormRow, Item, SubmitButton } from 'react-basics'; import { Dropdown, Form, FormButtons, FormInput, FormRow, Item, SubmitButton } from 'react-basics';
import BaseParameters from '../[reportId]/BaseParameters'; import { BaseParameters } from '../[reportId]/BaseParameters';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
export function RevenueParameters() { export function RevenueParameters() {

View file

@ -1,9 +1,9 @@
import Money from '@/assets/money.svg'; import Money from '@/assets/money.svg';
import { REPORT_TYPES } from '@/lib/constants'; import { REPORT_TYPES } from '@/lib/constants';
import Report from '../[reportId]/Report'; import { Report } from '../[reportId]/Report';
import ReportBody from '../[reportId]/ReportBody'; import { ReportBody } from '../[reportId]/ReportBody';
import ReportHeader from '../[reportId]/ReportHeader'; import { ReportHeader } from '../[reportId]/ReportHeader';
import ReportMenu from '../[reportId]/ReportMenu'; import { ReportMenu } from '../[reportId]/ReportMenu';
import { RevenueParameters } from './RevenueParameters'; import { RevenueParameters } from './RevenueParameters';
import { RevenueView } from './RevenueView'; import { RevenueView } from './RevenueView';

View file

@ -2,7 +2,7 @@ import { useContext } from 'react';
import { useMessages } from '@/components/hooks'; import { useMessages } from '@/components/hooks';
import { Form, FormButtons, SubmitButton } from 'react-basics'; import { Form, FormButtons, SubmitButton } from 'react-basics';
import { ReportContext } from '../[reportId]/Report'; import { ReportContext } from '../[reportId]/Report';
import BaseParameters from '../[reportId]/BaseParameters'; import { BaseParameters } from '../[reportId]/BaseParameters';
export function UTMParameters() { export function UTMParameters() {
const { report, runReport, isRunning } = useContext(ReportContext); const { report, runReport, isRunning } = useContext(ReportContext);

View file

@ -1,8 +1,8 @@
'use client'; 'use client';
import Report from '../[reportId]/Report'; import { Report } from '../[reportId]/Report';
import ReportHeader from '../[reportId]/ReportHeader'; import { ReportHeader } from '../[reportId]/ReportHeader';
import ReportMenu from '../[reportId]/ReportMenu'; import { ReportMenu } from '../[reportId]/ReportMenu';
import ReportBody from '../[reportId]/ReportBody'; import { ReportBody } from '../[reportId]/ReportBody';
import { UTMParameters } from './UTMParameters'; import { UTMParameters } from './UTMParameters';
import { UTMView } from './UTMView'; import { UTMView } from './UTMView';
import Tag from '@/assets/tag.svg'; import Tag from '@/assets/tag.svg';

View file

@ -1,5 +1,5 @@
'use client'; 'use client';
import WebsiteDetailsPage from '../../(main)/websites/[websiteId]/WebsiteDetailsPage'; import { WebsiteDetailsPage } from '../../(main)/websites/[websiteId]/WebsiteDetailsPage';
import { useShareToken } from '@/components/hooks'; import { useShareToken } from '@/components/hooks';
import { Page } from '@/components/layout/Page'; import { Page } from '@/components/layout/Page';
import { Header } from './Header'; import { Header } from './Header';

View file

@ -0,0 +1,3 @@
import { animated, AnimatedComponent } from '@react-spring/web';
export const AnimatedDiv: AnimatedComponent<any> = animated.div;

View file

@ -26,7 +26,7 @@ export function LanguageButton() {
<Button key={value} variant="quiet" onPress={() => handleSelect(value)}> <Button key={value} variant="quiet" onPress={() => handleSelect(value)}>
<Text <Text
weight={value === locale ? 'bold' : 'normal'} weight={value === locale ? 'bold' : 'normal'}
color={value === locale ? 'primary' : 'muted'} color={value === locale ? undefined : 'muted'}
> >
{label} {label}
</Text> </Text>

View file

@ -7,6 +7,4 @@
max-width: 1320px; max-width: 1320px;
margin: 0 auto; margin: 0 auto;
padding: 0 20px; padding: 0 20px;
min-height: calc(100vh - 60px);
min-height: calc(100dvh - 60px);
} }

View file

@ -1,6 +1,7 @@
import { FixedSizeList } from 'react-window'; import { FixedSizeList } from 'react-window';
import { useSpring, animated, config } from '@react-spring/web'; import { useSpring, config } from '@react-spring/web';
import classNames from 'classnames'; import classNames from 'classnames';
import { AnimatedDiv } from '@/components/common/AnimatedDiv';
import { Empty } from '@/components/common/Empty'; import { Empty } from '@/components/common/Empty';
import { formatLongNumber } from '@/lib/format'; import { formatLongNumber } from '@/lib/format';
import { useMessages } from '@/components/hooks'; import { useMessages } from '@/components/hooks';
@ -94,14 +95,14 @@ const AnimatedRow = ({ label, value = 0, percent, change, animate, showPercentag
<div className={styles.label}>{label}</div> <div className={styles.label}>{label}</div>
<div className={styles.value}> <div className={styles.value}>
{change} {change}
<animated.div className={styles.value} title={props?.y as any}> <AnimatedDiv className={styles.value} title={props?.y as any}>
{props.y?.to(formatLongNumber)} {props.y?.to(formatLongNumber)}
</animated.div> </AnimatedDiv>
</div> </div>
{showPercentage && ( {showPercentage && (
<div className={styles.percent}> <div className={styles.percent}>
<animated.div className={styles.bar} style={{ width: props.width.to(n => `${n}%`) }} /> <AnimatedDiv className={styles.bar} style={{ width: props.width.to(n => `${n}%`) }} />
<animated.span>{props.width.to(n => `${n?.toFixed?.(0)}%`)}</animated.span> <AnimatedDiv>{props.width.to(n => `${n?.toFixed?.(0)}%`)}</AnimatedDiv>
</div> </div>
)} )}
</div> </div>

View file

@ -1,6 +1,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { useSpring, animated } from '@react-spring/web'; import { useSpring } from '@react-spring/web';
import { formatNumber } from '@/lib/format'; import { formatNumber } from '@/lib/format';
import { AnimatedDiv } from '@/components/common/AnimatedDiv';
import { ChangeLabel } from '@/components/metrics/ChangeLabel'; import { ChangeLabel } from '@/components/metrics/ChangeLabel';
import styles from './MetricCard.module.css'; import styles from './MetricCard.module.css';
@ -37,9 +38,9 @@ export const MetricCard = ({
return ( return (
<div className={classNames(styles.card, className, showPrevious && styles.compare)}> <div className={classNames(styles.card, className, showPrevious && styles.compare)}>
{showLabel && <div className={styles.label}>{label}</div>} {showLabel && <div className={styles.label}>{label}</div>}
<animated.div className={styles.value} title={value?.toString()}> <AnimatedDiv className={styles.value} title={value?.toString()}>
{props?.x?.to(x => formatValue(x))} {props?.x?.to(x => formatValue(x))}
</animated.div> </AnimatedDiv>
{showChange && ( {showChange && (
<ChangeLabel <ChangeLabel
className={styles.change} className={styles.change}
@ -47,13 +48,13 @@ export const MetricCard = ({
title={formatValue(change)} title={formatValue(change)}
reverseColors={reverseColors} reverseColors={reverseColors}
> >
<animated.span>{changeProps?.x?.to(x => `${Math.abs(~~x)}%`)}</animated.span> <AnimatedDiv>{changeProps?.x?.to(x => `${Math.abs(~~x)}%`)}</AnimatedDiv>
</ChangeLabel> </ChangeLabel>
)} )}
{showPrevious && ( {showPrevious && (
<animated.div className={classNames(styles.value, styles.prev)} title={diff.toString()}> <AnimatedDiv className={classNames(styles.value, styles.prev)} title={diff.toString()}>
{prevProps?.x?.to(x => formatValue(x))} {prevProps?.x?.to(x => formatValue(x))}
</animated.div> </AnimatedDiv>
)} )}
</div> </div>
); );