Skip to content

Commit

Permalink
style(apps/analytics): organize performance analytics in tab structure (
Browse files Browse the repository at this point in the history
  • Loading branch information
sjschlapbach authored Dec 20, 2024
1 parent c5f02ce commit 09b14b1
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 157 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button } from '@uzh-bf/design-system'
import { Button, FormLabel } from '@uzh-bf/design-system'
import { useTranslations } from 'next-intl'
import { SetStateAction } from 'react'

Expand All @@ -12,25 +12,32 @@ function ActivitiesElementsSwitch({
const t = useTranslations()

return (
<div className="flex flex-row">
<Button
basic
onClick={() => setType('activity')}
className={{
root: `py-0.25 rounded-l border !border-r-0 border-solid px-2 ${type === 'activity' ? 'bg-primary-100 border-primary-100 text-white' : ''}`,
}}
>
{t('manage.analytics.activities')}
</Button>
<Button
basic
onClick={() => setType('instance')}
className={{
root: `rounded-r border !border-l-0 border-solid px-2 py-0.5 ${type === 'instance' ? 'bg-primary-100 border-primary-100 text-white' : ''}`,
}}
>
{t('manage.analytics.elements')}
</Button>
<div>
<FormLabel
label={t('manage.analytics.dataSource')}
labelType="small"
required={false}
/>
<div className="flex flex-row">
<Button
basic
onClick={() => setType('activity')}
className={{
root: `py-0.25 h-8 rounded-l border !border-r-0 border-solid px-2 ${type === 'activity' ? 'bg-primary-100 border-primary-100 text-white' : ''}`,
}}
>
{t('manage.analytics.activities')}
</Button>
<Button
basic
onClick={() => setType('instance')}
className={{
root: `h-8 rounded-r border !border-l-0 border-solid px-2 py-0.5 ${type === 'instance' ? 'bg-primary-100 border-primary-100 text-white' : ''}`,
}}
>
{t('manage.analytics.elements')}
</Button>
</div>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,38 +72,40 @@ function ActivityInstanceFeedbacksPlot({
instanceSearch,
})

const ResetButton = () => (
<Button
className={{
root: 'py-0.25 flex h-8 w-max flex-row items-center gap-2 self-end px-2 shadow-none',
}}
disabled={
type === defaultFilters.type &&
activityType === defaultFilters.activityType &&
elementType === defaultFilters.elementType &&
activitySearchTerm === defaultFilters.searchTerm &&
instanceSearchTerm === defaultFilters.searchTerm
}
onClick={() => {
setType(defaultFilters.type)
setActivityType(defaultFilters.activityType)
setElementType(defaultFilters.elementType)
setActivitySearch('')
setInstanceSearch('')
}}
>
<FontAwesomeIcon icon={faX} />
<div>{t('manage.analytics.resetSelectors')}</div>
</Button>
)

return (
<div className="border-uzh-grey-80 rounded-xl border border-solid p-3">
<div className="flex flex-row items-center justify-between">
<div className="mb-2 flex flex-row gap-8">
<H2>{t('manage.analytics.negativeFeedbackOverview')}</H2>
<ActivitiesElementsSwitch type={type} setType={setType} />
</div>
<Button
className={{
root: 'py-0.25 flex h-8 flex-row items-center gap-2 px-2',
}}
disabled={
type === defaultFilters.type &&
activityType === defaultFilters.activityType &&
elementType === defaultFilters.elementType &&
activitySearchTerm === defaultFilters.searchTerm &&
instanceSearchTerm === defaultFilters.searchTerm
}
onClick={() => {
setType(defaultFilters.type)
setActivityType(defaultFilters.activityType)
setElementType(defaultFilters.elementType)
setActivitySearch('')
setInstanceSearch('')
}}
>
<FontAwesomeIcon icon={faX} />
<div>{t('manage.analytics.resetSelectors')}</div>
</Button>
<div className="flex w-full flex-row justify-between gap-8">
<H2>{t('manage.analytics.feedbackOverviewActivityInstances')}</H2>
<ResetButton />
</div>
{type === 'activity' ? (
<div className="flex flex-row items-center gap-8">
<ActivitiesElementsSwitch type={type} setType={setType} />
<ActivityTypeFilter
activityType={activityType}
setActivityType={setActivityType}
Expand All @@ -116,6 +118,7 @@ function ActivityInstanceFeedbacksPlot({
</div>
) : (
<div className="flex flex-row items-center gap-8">
<ActivitiesElementsSwitch type={type} setType={setType} />
<ElementTypeFilter
elementType={elementType}
setElementType={setElementType}
Expand Down Expand Up @@ -145,9 +148,8 @@ function ActivityInstanceFeedbacksPlot({
wrapperStyle={{ top: 0, right: 0 }}
/>
<div className="flex flex-col pt-6">
{entries.length > 0 && (
<div className="max-h-[13rem] overflow-y-scroll">
{entries.map((feedback) => (
{entries.length > 0
? entries.map((feedback) => (
<ElementFeedbackBarChart
key={`upvotes-${feedback.id}`}
title={
Expand All @@ -160,9 +162,8 @@ function ActivityInstanceFeedbacksPlot({
feedback={feedback}
colors={chartColors}
/>
))}
</div>
)}
))
: null}
</div>
</div>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,60 +25,65 @@ function ActivityProgressPlot({
repeated: '#064e3b',
}

const ProgressLegend = () => (
<Legend
payload={[
{
value: t('manage.analytics.started'),
color: chartColors.started,
type: 'rect',
},
{
value: t('manage.analytics.completed'),
color: chartColors.completed,
type: 'rect',
},
{
value: t('manage.analytics.repeated'),
color: chartColors.repeated,
type: 'rect',
},
]}
wrapperStyle={{ bottom: 0, right: 0 }}
/>
)

return (
<div className="border-uzh-grey-80 rounded-xl border border-solid p-3">
<div className="relative">
<H2>{t('manage.analytics.asynchronousActivityProgress')}</H2>
<Legend
payload={[
{
value: t('manage.analytics.started'),
color: chartColors.started,
type: 'rect',
},
{
value: t('manage.analytics.completed'),
color: chartColors.completed,
type: 'rect',
},
{
value: t('manage.analytics.repeated'),
color: chartColors.repeated,
type: 'rect',
},
]}
wrapperStyle={{ bottom: 0, right: 0 }}
/>
</div>
<H2>{t('manage.analytics.asynchronousActivityProgress')}</H2>
<div className="flex flex-col gap-6">
{pqProgresses.length > 0 && (
<div>
<H4>{t('shared.generic.practiceQuizzes')}</H4>
<div className="max-h-[13rem] overflow-y-scroll">
{pqProgresses.map((progress, idx) => (
<StackedProgress
key={`activity-progress-pq-${idx}`}
progress={progress}
participants={participants}
colors={chartColors}
/>
))}
<div className="relative flex flex-row">
<H4>{t('shared.generic.practiceQuizzes')}</H4>
<ProgressLegend />
</div>
{pqProgresses.map((progress, idx) => (
<StackedProgress
key={`activity-progress-pq-${idx}`}
progress={progress}
participants={participants}
colors={chartColors}
showScale={idx === pqProgresses.length - 1}
/>
))}
</div>
)}
{mlProgresses.length > 0 && (
<div>
<H4>{t('shared.generic.microlearnings')}</H4>
<div className="max-h-[13rem] overflow-y-scroll">
{mlProgresses.map((progress, idx) => (
<StackedProgress
key={`activity-progress-ml-${idx}`}
progress={progress}
participants={participants}
colors={chartColors}
/>
))}
<div className="relative flex flex-row">
<H4>{t('shared.generic.microlearnings')}</H4>
<ProgressLegend />
</div>
{mlProgresses.map((progress, idx) => (
<StackedProgress
key={`activity-progress-ml-${idx}`}
progress={progress}
participants={participants}
colors={chartColors}
showScale={idx === mlProgresses.length - 1}
/>
))}
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,38 +71,42 @@ function PerformanceRates({
attemptsType
)

const ResetButton = () => (
<Button
className={{
root: 'py-0.25 flex h-8 w-max flex-row items-center gap-2 self-end px-2 shadow-none',
}}
disabled={
type === defaultFilters.type &&
attemptsType === defaultFilters.attemptsType &&
activityType === defaultFilters.activityType &&
elementType === defaultFilters.elementType
}
onClick={() => {
setType(defaultFilters.type)
setAttemptsType(defaultFilters.attemptsType)
setActivityType(defaultFilters.activityType)
setElementType(defaultFilters.elementType)
setActivitySearch('')
setInstanceSearch('')
}}
>
<FontAwesomeIcon icon={faX} />
<div>{t('manage.analytics.resetSelectors')}</div>
</Button>
)

return (
<div className="border-uzh-grey-80 rounded-xl border border-solid p-3">
<div className="flex flex-row items-center justify-between">
<div className="mb-2 flex flex-row gap-8">
<div className="flex w-full flex-row justify-between gap-8">
<H2>{t('manage.analytics.activityElementPerformanceRates')}</H2>
<ActivitiesElementsSwitch type={type} setType={setType} />
<ResetButton />
</div>
<Button
className={{
root: 'py-0.25 flex h-8 flex-row items-center gap-2 px-2',
}}
disabled={
type === defaultFilters.type &&
attemptsType === defaultFilters.attemptsType &&
activityType === defaultFilters.activityType &&
elementType === defaultFilters.elementType
}
onClick={() => {
setType(defaultFilters.type)
setAttemptsType(defaultFilters.attemptsType)
setActivityType(defaultFilters.activityType)
setElementType(defaultFilters.elementType)
setActivitySearch('')
setInstanceSearch('')
}}
>
<FontAwesomeIcon icon={faX} />
<div>{t('manage.analytics.resetSelectors')}</div>
</Button>
</div>
{type === 'activity' ? (
<div className="flex flex-row items-center gap-8">
<div className="mb-3 flex flex-col gap-1 lg:flex-row lg:gap-8">
<ActivitiesElementsSwitch type={type} setType={setType} />
<PerformanceAttemptsFilter
attemptsType={attemptsType}
setAttemptsType={setAttemptsType}
Expand All @@ -118,7 +122,8 @@ function PerformanceRates({
/>
</div>
) : (
<div className="flex flex-row items-center gap-8">
<div className="mb-3 flex flex-col gap-1 lg:flex-row lg:gap-8">
<ActivitiesElementsSwitch type={type} setType={setType} />
<PerformanceAttemptsFilter
attemptsType={attemptsType}
setAttemptsType={setAttemptsType}
Expand All @@ -134,6 +139,7 @@ function PerformanceRates({
/>
</div>
)}

{entries.length > 0 ? (
<div className="relative">
<Legend
Expand All @@ -157,18 +163,16 @@ function PerformanceRates({
wrapperStyle={{ top: 0, right: 0 }}
/>
<div className="flex flex-col pt-6">
{entries.length > 0 && (
<div className="max-h-[13rem] overflow-y-scroll">
{entries.map((progress) => (
{entries.length > 0
? entries.map((progress) => (
<PerformanceRatesBarChart
key={`performance-rates-${progress.id}`}
title={progress.name}
rates={progress}
colors={chartColors}
/>
))}
</div>
)}
))
: null}
</div>
</div>
) : (
Expand Down
Loading

0 comments on commit 09b14b1

Please sign in to comment.