Funnel report updates. Fixed insights report.

This commit is contained in:
Mike Cao 2024-04-03 14:44:49 -07:00
parent 3aee54009c
commit cf8d49f867
8 changed files with 94 additions and 47 deletions

View File

@ -191,7 +191,7 @@ export default function FieldFilterEditForm({
)} )}
</Flexbox> </Flexbox>
<Button variant="primary" onClick={handleAdd} disabled={isDisabled}> <Button variant="primary" onClick={handleAdd} disabled={isDisabled}>
{isNew ? formatMessage(labels.add) : formatMessage(labels.update)} {formatMessage(isNew ? labels.add : labels.update)}
</Button> </Button>
</FormRow> </FormRow>
</Form> </Form>

View File

@ -74,7 +74,8 @@ export function FilterParameters() {
return ( return (
<ParameterList.Item key={name} onRemove={() => handleRemove(name)}> <ParameterList.Item key={name} onRemove={() => handleRemove(name)}>
<FilterParameter <FilterParameter
{...dateRange} startDate={dateRange.startDate}
endDate={dateRange.endDate}
websiteId={websiteId} websiteId={websiteId}
name={name} name={name}
label={label} label={label}

View File

@ -4,6 +4,7 @@ import Icons from 'components/icons';
import Empty from 'components/common/Empty'; import Empty from 'components/common/Empty';
import { useMessages } from 'components/hooks'; import { useMessages } from 'components/hooks';
import styles from './ParameterList.module.css'; import styles from './ParameterList.module.css';
import classNames from 'classnames';
export interface ParameterListProps { export interface ParameterListProps {
children?: ReactNode; children?: ReactNode;
@ -22,15 +23,17 @@ export function ParameterList({ children }: ParameterListProps) {
const Item = ({ const Item = ({
children, children,
className,
onClick, onClick,
onRemove, onRemove,
}: { }: {
children?: ReactNode; children?: ReactNode;
className?: string;
onClick?: () => void; onClick?: () => void;
onRemove?: () => void; onRemove?: () => void;
}) => { }) => {
return ( return (
<div className={styles.item} onClick={onClick}> <div className={classNames(styles.item, className)} onClick={onClick}>
{children} {children}
<Icon onClick={onRemove}> <Icon onClick={onRemove}>
<Icons.Close /> <Icons.Close />

View File

@ -37,7 +37,7 @@
.card { .card {
display: grid; display: grid;
gap: 20px; gap: 20px;
margin-top: 8px; margin-top: 14px;
} }
.header { .header {
@ -73,7 +73,7 @@
} }
.item { .item {
font-size: 24px; font-size: 20px;
color: var(--base900); color: var(--base900);
font-weight: 700; font-weight: 700;
} }
@ -83,19 +83,19 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: 10px; gap: 10px;
font-size: 24px;
margin: 10px 0; margin: 10px 0;
text-transform: lowercase; text-transform: lowercase;
} }
.visitors { .visitors {
color: var(--base900); color: var(--base900);
font-size: 32px; font-size: 24px;
font-weight: 900; font-weight: 900;
margin-right: 10px; margin-right: 10px;
} }
.percent { .percent {
font-size: 20px;
font-weight: 700; font-weight: 700;
align-self: flex-end; align-self: flex-end;
} }

View File

@ -2,8 +2,15 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
width: 100%;
} }
.type { .type {
color: var(--base700); color: var(--base700);
} }
.value {
display: flex;
align-self: center;
gap: 20px;
}

View File

@ -41,6 +41,17 @@ export function FunnelParameters() {
updateReport({ parameters: { steps: parameters.steps.concat(step) } }); updateReport({ parameters: { steps: parameters.steps.concat(step) } });
}; };
const handleUpdateStep = (
close: () => void,
index: number,
step: { type: string; value: string },
) => {
const steps = [...parameters.steps];
steps[index] = step;
updateReport({ parameters: { steps } });
close();
};
const handleRemoveStep = (index: number) => { const handleRemoveStep = (index: number) => {
const steps = [...parameters.steps]; const steps = [...parameters.steps];
delete steps[index]; delete steps[index];
@ -57,7 +68,7 @@ export function FunnelParameters() {
</Button> </Button>
<Popup alignment="start"> <Popup alignment="start">
<PopupForm> <PopupForm>
<FunnelStepAddForm onAdd={handleAddStep} /> <FunnelStepAddForm onChange={handleAddStep} />
</PopupForm> </PopupForm>
</Popup> </Popup>
</PopupTrigger> </PopupTrigger>
@ -79,14 +90,30 @@ export function FunnelParameters() {
<ParameterList> <ParameterList>
{steps.map((step: { type: string; value: string }, index: number) => { {steps.map((step: { type: string; value: string }, index: number) => {
return ( return (
<ParameterList.Item key={index} onRemove={() => handleRemoveStep(index)}> <PopupTrigger key={index}>
<div className={styles.item}> <ParameterList.Item
<div className={styles.type}> className={styles.item}
<Icon>{step.type === 'url' ? <Icons.Eye /> : <Icons.Bolt />}</Icon> onRemove={() => handleRemoveStep(index)}
>
<div className={styles.value}>
<div className={styles.type}>
<Icon>{step.type === 'url' ? <Icons.Eye /> : <Icons.Bolt />}</Icon>
</div>
<div>{step.value}</div>
</div> </div>
<div>{step.value}</div> </ParameterList.Item>
</div> <Popup alignment="start">
</ParameterList.Item> {(close: () => void) => (
<PopupForm>
<FunnelStepAddForm
type={step.type}
value={step.value}
onChange={handleUpdateStep.bind(null, close, index)}
/>
</PopupForm>
)}
</Popup>
</PopupTrigger>
); );
})} })}
</ParameterList> </ParameterList>

View File

@ -3,13 +3,18 @@ import { useMessages } from 'components/hooks';
import { Button, FormRow, TextField, Flexbox, Dropdown, Item } from 'react-basics'; import { Button, FormRow, TextField, Flexbox, Dropdown, Item } from 'react-basics';
import styles from './FunnelStepAddForm.module.css'; import styles from './FunnelStepAddForm.module.css';
export interface UrlAddFormProps { export interface FunnelStepAddFormProps {
defaultValue?: string; type?: string;
onAdd?: (step: { type: string; value: string }) => void; value?: string;
onChange?: (step: { type: string; value: string }) => void;
} }
export function FunnelStepAddForm({ defaultValue = '', onAdd }: UrlAddFormProps) { export function FunnelStepAddForm({
const [type, setType] = useState('url'); type: defaultType = 'url',
value: defaultValue = '',
onChange,
}: FunnelStepAddFormProps) {
const [type, setType] = useState(defaultType);
const [value, setValue] = useState(defaultValue); const [value, setValue] = useState(defaultValue);
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const items = [ const items = [
@ -19,7 +24,7 @@ export function FunnelStepAddForm({ defaultValue = '', onAdd }: UrlAddFormProps)
const isDisabled = !type || !value; const isDisabled = !type || !value;
const handleSave = () => { const handleSave = () => {
onAdd({ type, value }); onChange({ type, value });
setValue(''); setValue('');
}; };
@ -39,32 +44,36 @@ export function FunnelStepAddForm({ defaultValue = '', onAdd }: UrlAddFormProps)
}; };
return ( return (
<FormRow label={formatMessage(labels.addStep)}> <Flexbox direction="column" gap={10}>
<Flexbox gap={10}> <FormRow label={formatMessage(defaultValue ? labels.update : labels.add)}>
<Dropdown <Flexbox gap={10}>
className={styles.dropdown} <Dropdown
items={items} className={styles.dropdown}
value={type} items={items}
renderValue={renderTypeValue} value={type}
onChange={(value: any) => setType(value)} renderValue={renderTypeValue}
> onChange={(value: any) => setType(value)}
{({ value, label }) => { >
return <Item key={value}>{label}</Item>; {({ value, label }) => {
}} return <Item key={value}>{label}</Item>;
</Dropdown> }}
<TextField </Dropdown>
className={styles.input} <TextField
value={value} className={styles.input}
onChange={handleChange} value={value}
autoFocus={true} onChange={handleChange}
autoComplete="off" autoFocus={true}
onKeyDown={handleKeyDown} autoComplete="off"
/> onKeyDown={handleKeyDown}
/>
</Flexbox>
</FormRow>
<FormRow>
<Button variant="primary" onClick={handleSave} disabled={isDisabled}> <Button variant="primary" onClick={handleSave} disabled={isDisabled}>
{formatMessage(labels.add)} {formatMessage(defaultValue ? labels.update : labels.add)}
</Button> </Button>
</Flexbox> </FormRow>
</FormRow> </Flexbox>
); );
} }

View File

@ -56,8 +56,8 @@ const schema = {
}; };
function convertFilters(filters: any[]) { function convertFilters(filters: any[]) {
return filters.reduce((obj, { name, ...value }) => { return filters.reduce((obj, filter) => {
obj[name] = value; obj[filter.name] = filter;
return obj; return obj;
}, {}); }, {});