packages/experiments/src/components/ExperimentsDebugger.tsx
import { Slider, Typography } from '@mui/material'
import { FlexCol, FlexRow } from '@xylabs/react-flexbox'
import { useLocalStorage } from '@xylabs/react-shared'
import React from 'react'
import type {
ExperimentsData, OutcomesData, VariantData,
} from './models/index.ts'
import { ExperimentsLocalStorageKey, OutcomesLocalStorageKey } from './models/index.ts'
const ExperimentsDebugger: React.FC = ({ ...props }) => {
const [experiments] = useLocalStorage<ExperimentsData>(ExperimentsLocalStorageKey, {})
const [outcomes, setOutcomes] = useLocalStorage<OutcomesData>(OutcomesLocalStorageKey, {})
const sumUpVariants = (items: VariantData[]) => items.reduce((acc, curr) => acc + curr.weight, 0)
const experimentEntries = Object.entries(experiments)
if (!experiments || experimentEntries.length === 0) {
return (
<FlexCol alignItems="stretch" {...props}>
<Typography variant="subtitle1">No Experiments loaded</Typography>
<Typography variant="subtitle2">Visit a page with an experiment to load the data</Typography>
</FlexCol>
)
}
return (
<FlexCol alignItems="stretch" {...props}>
{Object.entries(experiments).map((data) => {
const [name, experiment] = data
const outcome = (outcomes[name] || 0) as number
const marks = [
{ label: `${experiment.variants[0].name} | ${experiment.variants[0].weight}`, value: 0 },
...experiment.variants.map(({ weight }, index) => ({
label: index === experiment.variants.length - 1 ? 'End' : `${experiment.variants[index + 1].name} | ${weight}`,
value: index === 0 ? weight : sumUpVariants(experiment.variants.slice(0, index + 1)),
})),
]
return (
<FlexCol key={`experiment-${name}`} alignItems="stretch" paddingX={4} marginBottom={4} {...props}>
<FlexRow>
{name}
:
{outcome}
</FlexRow>
<FlexRow>
<Slider
aria-label={`Experiment ${name}`}
defaultValue={outcome}
value={outcome}
marks={marks}
onChange={(e, value) => {
const truncated = Number((Array.isArray(value) ? value[0] : value).toFixed(2))
outcomes[name] = truncated
// Spread operator triggers rerender
setOutcomes({ ...outcomes })
}}
/>
</FlexRow>
</FlexCol>
)
})}
</FlexCol>
)
}
export { ExperimentsDebugger }