From fea2b8736fef4bbdfd095773ffab5e5e1351da45 Mon Sep 17 00:00:00 2001 From: "Abdullah." <125115953+mabdullahabaid@users.noreply.github.com> Date: Fri, 26 Jun 2026 20:57:21 +0500 Subject: [PATCH] feat(website): rebuild dashboard visual faithful to twenty-front (#22218) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rebuilds the product-feature **DashboardVisual** to mirror twenty-front's dashboard widgets, with colors traced to twenty-front's actual source rather than eyeballed. ## Widgets - **Bar — "Deals by month"**: single-series `blue8` (twenty-front's `GRAPH_DEFAULT_COLOR`), dashed `4 4` gridlines, value labels, nice rounded Y-ticks. Replaces the old stacked bar (stacked bars aren't used in twenty-front). - **Donut — "Deals by stage"**: the real opportunity pipeline (New/Screening/Meeting/Proposal/Customer), each segment colored by that stage option's own color from the metadata (`red/purple/sky/turquoise/yellow`), with a center total and a paginated horizontal legend. - **KPIs**: big-number cards (Revenue YTD / Avg deal size / Win rate). ## Responsive — `mediaUp('md')` The dashboard is the full-width spotlight tile, whose frame is short below md and grows to 420px at md+. So the layout keys off md: below it collapses to **2-up KPIs + a full-width bar** (donut and the 3rd KPI hidden, smaller breadcrumb), and the spotlight frame's mobile min-height is bumped so the bar has room; at md+ the full 3-KPI + side-by-side layout returns. The donut caps at its size and shrinks with its container. ## Notes - Follows the `product-feature` conventions (per-visual folder, one-export-per-file, split types). - `Tiles.tsx`: one-line spotlight mobile min-height bump (only the dashboard uses the spotlight tile). - typecheck + lint + build all green. image --- .../DashboardVisual/DashboardVisual.tsx | 108 +++++++---- .../DashboardVisual/components/BarChart.tsx | 164 +++++++++------- .../DashboardVisual/components/DonutChart.tsx | 181 ++++++++++++------ .../DashboardVisual/components/KpiCard.tsx | 11 +- .../data/dashboard-visual-data.ts | 36 ++-- .../DashboardVisual/types/dashboard-kpi.ts | 5 +- .../DashboardVisual/types/dashboard-month.ts | 7 +- .../types/dashboard-stage-tone.ts | 7 +- .../DashboardVisual/types/dashboard-stage.ts | 6 +- .../product-feature/components/Tiles.tsx | 2 +- 10 files changed, 342 insertions(+), 185 deletions(-) diff --git a/packages/twenty-website/src/sections/product-feature/DashboardVisual/DashboardVisual.tsx b/packages/twenty-website/src/sections/product-feature/DashboardVisual/DashboardVisual.tsx index 7d545fb884..2d8cde0c96 100644 --- a/packages/twenty-website/src/sections/product-feature/DashboardVisual/DashboardVisual.tsx +++ b/packages/twenty-website/src/sections/product-feature/DashboardVisual/DashboardVisual.tsx @@ -1,10 +1,13 @@ 'use client'; +import { msg } from '@lingui/core/macro'; +import { useLingui } from '@lingui/react'; import { styled } from '@linaria/react'; import { IconDotsVertical, IconLayoutDashboard } from '@tabler/icons-react'; import { THEME_LIGHT } from 'twenty-ui/theme'; import { previewFontSize } from '@/app-preview/preview-font-size'; +import { mediaUp } from '@/tokens'; import { BarChart } from './components/BarChart'; import { DonutChart } from './components/DonutChart'; @@ -45,13 +48,21 @@ const BreadcrumbIcon = styled.span` const BreadcrumbText = styled.span` color: ${THEME_LIGHT.font.color.secondary}; - font-size: ${previewFontSize(THEME_LIGHT.font.size.md)}; + font-size: ${previewFontSize(THEME_LIGHT.font.size.sm)}; + + ${mediaUp('md')} { + font-size: ${previewFontSize(THEME_LIGHT.font.size.md)}; + } `; const BreadcrumbCurrent = styled.span` color: ${THEME_LIGHT.font.color.primary}; - font-size: ${previewFontSize(THEME_LIGHT.font.size.md)}; + font-size: ${previewFontSize(THEME_LIGHT.font.size.sm)}; font-weight: ${THEME_LIGHT.font.weight.medium}; + + ${mediaUp('md')} { + font-size: ${previewFontSize(THEME_LIGHT.font.size.md)}; + } `; const Actions = styled.div` @@ -83,15 +94,40 @@ const SearchChip = styled.span` const Body = styled.div` background-color: ${THEME_LIGHT.background.primary}; - display: grid; + display: flex; flex: 1; + flex-direction: column; gap: 8px; - grid-template-columns: repeat(3, 1fr); - grid-template-rows: auto 1fr; min-height: 0; padding: 12px; `; +const KpiRow = styled.div` + display: grid; + flex-shrink: 0; + gap: 8px; + grid-template-columns: repeat(2, 1fr); + + & > :nth-child(3) { + display: none; + } + + ${mediaUp('md')} { + grid-template-columns: repeat(3, 1fr); + + & > :nth-child(3) { + display: flex; + } + } +`; + +const ChartRow = styled.div` + display: flex; + flex: 1; + gap: 8px; + min-height: 0; +`; + const WidgetCard = styled.div` background-color: ${THEME_LIGHT.background.secondary}; border: 1px solid ${THEME_LIGHT.border.color.light}; @@ -99,15 +135,24 @@ const WidgetCard = styled.div` display: flex; flex-direction: column; min-height: 0; + min-width: 0; padding: 8px; &[data-cell='bar'] { - grid-column: 1 / 3; - grid-row: 2; + flex: 1; } &[data-cell='donut'] { - grid-column: 3; - grid-row: 2; + display: none; + } + + ${mediaUp('md')} { + &[data-cell='bar'] { + flex: 1.4; + } + &[data-cell='donut'] { + display: flex; + flex: 1; + } } `; @@ -122,6 +167,8 @@ const WidgetHeader = styled.span` `; export function DashboardVisual({ active }: { active: boolean }) { + const { i18n } = useLingui(); + return ( @@ -129,8 +176,10 @@ export function DashboardVisual({ active }: { active: boolean }) { - Dashboards / - Sales performance + {i18n._(msg`Dashboards`)} / + + {i18n._(msg`Sales performance`)} + @@ -140,28 +189,23 @@ export function DashboardVisual({ active }: { active: boolean }) { - {DASHBOARD_VISUAL_DATA.kpis.map((kpi) => ( - - {kpi.label} - + + {DASHBOARD_VISUAL_DATA.kpis.map((kpi) => ( + + + + ))} + + + + {i18n._(msg`Deals by month`)} + - ))} - - Deals by month - - - - Deals by stage - - + + {i18n._(msg`Deals by stage`)} + + + ); diff --git a/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/BarChart.tsx b/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/BarChart.tsx index 978bb417c0..a80451f32f 100644 --- a/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/BarChart.tsx +++ b/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/BarChart.tsx @@ -1,5 +1,6 @@ 'use client'; +import { useLingui } from '@lingui/react'; import { styled } from '@linaria/react'; import { THEME_LIGHT } from 'twenty-ui/theme'; @@ -7,10 +8,10 @@ import { previewFontSize } from '@/app-preview/preview-font-size'; import { EASING } from '@/tokens'; import { type DashboardMonth } from '../types/dashboard-month'; -import { type DashboardStage } from '../types/dashboard-stage'; -const Y_TICK_COUNT = 5; const X_LABEL_ROW_HEIGHT = 18; +const TARGET_TICK_COUNT = 4; +const BAR_MAX_WIDTH = 26; const Root = styled.div` display: flex; @@ -48,12 +49,25 @@ const Bars = styled.div` min-width: 0; `; +const PlotArea = styled.div` + flex: 1; + min-height: 0; + position: relative; +`; + +const GridLine = styled.div` + border-top: 1px dashed ${THEME_LIGHT.border.color.light}; + left: 0; + position: absolute; + right: 0; +`; + const BarsRow = styled.div` align-items: flex-end; display: flex; - flex: 1; gap: 6px; - min-height: 0; + inset: 0; + position: absolute; `; const BarColumn = styled.div` @@ -62,41 +76,35 @@ const BarColumn = styled.div` flex: 1; height: 100%; justify-content: center; + position: relative; `; -const Stack = styled.div` - border-radius: 3px 3px 0 0; - display: flex; - flex-direction: column-reverse; - min-height: 2px; - overflow: hidden; +const Bar = styled.div` + background-color: ${THEME_LIGHT.color.blue8}; + border-radius: ${THEME_LIGHT.border.radius.sm} ${THEME_LIGHT.border.radius.sm} + 0 0; + max-width: ${BAR_MAX_WIDTH}px; transform-origin: bottom; transition: transform 0.8s ${EASING.standard}, filter 0.15s ease; - width: 68%; + width: 58%; &:hover { filter: brightness(1.08); } `; -const Segment = styled.div` - flex-shrink: 0; - width: 100%; - - &[data-tone='blue'] { - background-color: ${THEME_LIGHT.color.blue8}; - } - &[data-tone='purple'] { - background-color: ${THEME_LIGHT.color.purple8}; - } - &[data-tone='turquoise'] { - background-color: ${THEME_LIGHT.color.turquoise8}; - } - &[data-tone='orange'] { - background-color: ${THEME_LIGHT.color.orange8}; - } +const ValueLabel = styled.span` + color: ${THEME_LIGHT.font.color.light}; + font-size: ${previewFontSize(THEME_LIGHT.font.size.xs)}; + font-variant-numeric: tabular-nums; + left: 0; + position: absolute; + right: 0; + text-align: center; + transform: translateY(-3px); + transition: opacity 0.4s ${EASING.standard}; `; const XLabels = styled.div` @@ -113,67 +121,83 @@ const XLabel = styled.span` text-align: center; `; +function getNiceScale(maxValue: number): { maxTick: number; ticks: number[] } { + if (!(maxValue > 0)) { + return { maxTick: 1, ticks: [0, 1] }; + } + const rawStep = maxValue / TARGET_TICK_COUNT; + const magnitude = 10 ** Math.floor(Math.log10(rawStep)); + const normalized = rawStep / magnitude; + const niceNormalized = + normalized <= 1 ? 1 : normalized <= 2 ? 2 : normalized <= 5 ? 5 : 10; + const step = niceNormalized * magnitude; + const tickCount = Math.ceil(maxValue / step); + return { + maxTick: step * tickCount, + ticks: Array.from({ length: tickCount + 1 }, (_, index) => index * step), + }; +} + export function BarChart({ active, months, - stages, }: { active: boolean; months: DashboardMonth[]; - stages: DashboardStage[]; }) { - const monthlyTotals = months.map((month) => - month.values.reduce((sum, value) => sum + value, 0), - ); - const tickStep = Math.ceil( - (Math.max(...monthlyTotals) * 1.05) / Y_TICK_COUNT, - ); - const topTick = tickStep * Y_TICK_COUNT; - const yTicks = Array.from( - { length: Y_TICK_COUNT + 1 }, - (_, tickNumber) => tickNumber * tickStep, - ); + const { i18n } = useLingui(); + const maxValue = Math.max(...months.map((month) => month.value)); + const { maxTick, ticks } = getNiceScale(maxValue); return ( - {yTicks.toReversed().map((tick) => ( + {ticks.toReversed().map((tick) => ( {tick} ))} - - {months.map((month, columnNumber) => { - const total = monthlyTotals[columnNumber]; - return ( - - - {stages.map((stage, stageNumber) => ( - - ))} - - - ); - })} - + + {ticks.map((tick) => ( + + ))} + + {months.map((month, columnNumber) => { + const heightPercent = (month.value / maxTick) * 100; + return ( + + + {month.value} + + + + ); + })} + + {months.map((month) => ( - {month.label} + {i18n._(month.label)} ))} diff --git a/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/DonutChart.tsx b/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/DonutChart.tsx index d12ab66da9..6ebff1b3cb 100644 --- a/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/DonutChart.tsx +++ b/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/DonutChart.tsx @@ -1,6 +1,10 @@ 'use client'; +import { msg } from '@lingui/core/macro'; +import { useLingui } from '@lingui/react'; import { styled } from '@linaria/react'; +import { IconChevronLeft, IconChevronRight } from '@tabler/icons-react'; +import { useState } from 'react'; import { THEME_LIGHT } from 'twenty-ui/theme'; import { previewFontSize } from '@/app-preview/preview-font-size'; @@ -8,33 +12,41 @@ import { EASING } from '@/tokens'; import { type DashboardStage } from '../types/dashboard-stage'; -const SIZE = 96; -const STROKE = 16; +const SIZE = 160; +const STROKE = 18; const RADIUS = (SIZE - STROKE) / 2; const CENTER = SIZE / 2; const CIRCUMFERENCE = 2 * Math.PI * RADIUS; +const GAP = CIRCUMFERENCE * 0.008; +const LEGEND_PAGE_SIZE = 3; const Root = styled.div` align-items: center; display: flex; flex: 1; flex-direction: column; - gap: 14px; + gap: 16px; justify-content: center; min-height: 0; `; const ChartArea = styled.div` - flex-shrink: 0; + aspect-ratio: 1; + max-height: 100%; + max-width: ${SIZE}px; + min-height: 0; position: relative; + width: 100%; `; const Ring = styled.svg` display: block; + height: 100%; transform-origin: center; transition: opacity 0.5s ${EASING.standard}, transform 0.5s ${EASING.standard}; + width: 100%; `; const Slice = styled.circle` @@ -46,17 +58,20 @@ const Slice = styled.circle` filter: brightness(1.1); } - &[data-tone='blue'] { - stroke: ${THEME_LIGHT.color.blue8}; + &[data-tone='red'] { + stroke: ${THEME_LIGHT.color.red8}; } &[data-tone='purple'] { stroke: ${THEME_LIGHT.color.purple8}; } + &[data-tone='sky'] { + stroke: ${THEME_LIGHT.color.sky8}; + } &[data-tone='turquoise'] { stroke: ${THEME_LIGHT.color.turquoise8}; } - &[data-tone='orange'] { - stroke: ${THEME_LIGHT.color.orange8}; + &[data-tone='yellow'] { + stroke: ${THEME_LIGHT.color.yellow8}; } `; @@ -78,113 +93,159 @@ const CenterValue = styled.span` `; const CenterLabel = styled.span` - color: ${THEME_LIGHT.font.color.light}; + color: ${THEME_LIGHT.font.color.tertiary}; font-size: ${previewFontSize(THEME_LIGHT.font.size.xs)}; margin-top: 2px; `; const Legend = styled.div` + align-items: center; display: flex; - flex-direction: column; - gap: 6px; + gap: 48px; + overflow: hidden; width: 100%; `; -const LegendRow = styled.div` +const Pager = styled.div` align-items: center; display: flex; - gap: 6px; + flex-shrink: 0; + gap: 2px; `; -const LegendDot = styled.span` +const PagerArrow = styled.span` + align-items: center; + color: ${THEME_LIGHT.font.color.light}; + cursor: pointer; + display: inline-flex; + transition: color 0.15s ease; + + &:hover { + color: ${THEME_LIGHT.font.color.secondary}; + } +`; + +const PagerText = styled.span` + color: ${THEME_LIGHT.font.color.light}; + font-size: ${previewFontSize(THEME_LIGHT.font.size.sm)}; + font-variant-numeric: tabular-nums; +`; + +const Item = styled.div` + align-items: center; + display: flex; + flex-shrink: 0; + gap: 5px; +`; + +const ItemDot = styled.span` border-radius: ${THEME_LIGHT.border.radius.xs}; flex-shrink: 0; - height: 8px; - width: 8px; + height: 9px; + width: 9px; - &[data-tone='blue'] { - background-color: ${THEME_LIGHT.color.blue8}; + &[data-tone='red'] { + background-color: ${THEME_LIGHT.color.red8}; } &[data-tone='purple'] { background-color: ${THEME_LIGHT.color.purple8}; } + &[data-tone='sky'] { + background-color: ${THEME_LIGHT.color.sky8}; + } &[data-tone='turquoise'] { background-color: ${THEME_LIGHT.color.turquoise8}; } - &[data-tone='orange'] { - background-color: ${THEME_LIGHT.color.orange8}; + &[data-tone='yellow'] { + background-color: ${THEME_LIGHT.color.yellow8}; } `; -const LegendLabel = styled.span` - color: ${THEME_LIGHT.font.color.secondary}; - flex: 1; - font-size: ${previewFontSize(THEME_LIGHT.font.size.md)}; -`; - -const LegendValue = styled.span` - color: ${THEME_LIGHT.font.color.tertiary}; - font-size: ${previewFontSize(THEME_LIGHT.font.size.md)}; - font-variant-numeric: tabular-nums; +const ItemLabel = styled.span` + color: ${THEME_LIGHT.font.color.primary}; + font-size: ${previewFontSize(THEME_LIGHT.font.size.sm)}; + font-weight: ${THEME_LIGHT.font.weight.medium}; + white-space: nowrap; `; export function DonutChart({ active, stages, - values, }: { active: boolean; stages: DashboardStage[]; - values: number[]; }) { - const total = values.reduce((sum, value) => sum + value, 0); + const { i18n } = useLingui(); + const [page, setPage] = useState(0); + const total = stages.reduce((sum, stage) => sum + stage.value, 0); + const pageCount = Math.ceil(stages.length / LEGEND_PAGE_SIZE); + const visibleStages = stages.slice( + page * LEGEND_PAGE_SIZE, + page * LEGEND_PAGE_SIZE + LEGEND_PAGE_SIZE, + ); let cumulative = 0; - const slices = stages.map((stage, stageNumber) => { - const value = values[stageNumber]; - const arc = (value / total) * CIRCUMFERENCE; - const startAngle = -90 + (cumulative / total) * 360; - cumulative += value; - return { arc, stage, startAngle, value }; + const slices = stages.map((stage) => { + const arc = total > 0 ? (stage.value / total) * CIRCUMFERENCE : 0; + const startAngle = -90 + (total > 0 ? cumulative / total : 0) * 360; + cumulative += stage.value; + return { arc, stage, startAngle }; }); return ( - {slices.map(({ arc, stage, startAngle }) => ( - - ))} + {slices.map(({ arc, stage, startAngle }) => { + const visibleArc = stage.value > 0 ? Math.max(arc - GAP, 0.5) : 0; + return ( + + ); + })}
{total} - Deals + {i18n._(msg`Total`)}
- {slices.map(({ stage, value }) => ( - - - {stage.label} - {value} - + + + setPage((current) => (current - 1 + pageCount) % pageCount) + } + > + + + + {page + 1}/{pageCount} + + setPage((current) => (current + 1) % pageCount)} + > + + + + {visibleStages.map((stage) => ( + + + {i18n._(stage.label)} + ))}
diff --git a/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/KpiCard.tsx b/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/KpiCard.tsx index 88c6844ca6..b6187c5603 100644 --- a/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/KpiCard.tsx +++ b/packages/twenty-website/src/sections/product-feature/DashboardVisual/components/KpiCard.tsx @@ -1,3 +1,4 @@ +import { useLingui } from '@lingui/react'; import { styled } from '@linaria/react'; import { IconTrendingDown, IconTrendingUp } from '@tabler/icons-react'; import { THEME_LIGHT } from 'twenty-ui/theme'; @@ -15,6 +16,11 @@ const Body = styled.div` justify-content: center; `; +const Label = styled.span` + color: ${THEME_LIGHT.font.color.secondary}; + font-size: ${previewFontSize(THEME_LIGHT.font.size.md)}; +`; + const Value = styled.span` color: ${THEME_LIGHT.font.color.primary}; font-size: ${previewFontSize(THEME_LIGHT.font.size.xxl)}; @@ -42,13 +48,16 @@ const TrendIcon = styled.span` `; const TrendPercent = styled.span` - color: ${THEME_LIGHT.font.color.secondary}; + color: ${THEME_LIGHT.font.color.light}; font-size: ${previewFontSize(THEME_LIGHT.font.size.xs)}; `; export function KpiCard({ kpi }: { kpi: DashboardKpi }) { + const { i18n } = useLingui(); + return ( + {kpi.value} diff --git a/packages/twenty-website/src/sections/product-feature/DashboardVisual/data/dashboard-visual-data.ts b/packages/twenty-website/src/sections/product-feature/DashboardVisual/data/dashboard-visual-data.ts index 0ebd9dd9be..7e2eb862dd 100644 --- a/packages/twenty-website/src/sections/product-feature/DashboardVisual/data/dashboard-visual-data.ts +++ b/packages/twenty-website/src/sections/product-feature/DashboardVisual/data/dashboard-visual-data.ts @@ -1,3 +1,5 @@ +import { msg } from '@lingui/core/macro'; + import { type DashboardKpi } from '../types/dashboard-kpi'; import { type DashboardMonth } from '../types/dashboard-month'; import { type DashboardStage } from '../types/dashboard-stage'; @@ -6,39 +8,41 @@ export const DASHBOARD_VISUAL_DATA: { byMonth: DashboardMonth[]; kpis: DashboardKpi[]; stages: DashboardStage[]; - stageTotals: number[]; } = { stages: [ - { label: 'New', tone: 'blue' }, - { label: 'Qualified', tone: 'purple' }, - { label: 'Proposal', tone: 'turquoise' }, - { label: 'Won', tone: 'orange' }, + { id: 'new', label: msg`New`, tone: 'red', value: 47 }, + { id: 'screening', label: msg`Screening`, tone: 'purple', value: 34 }, + { id: 'meeting', label: msg`Meeting`, tone: 'sky', value: 27 }, + { id: 'proposal', label: msg`Proposal`, tone: 'turquoise', value: 20 }, + { id: 'customer', label: msg`Customer`, tone: 'yellow', value: 12 }, ], - stageTotals: [47, 34, 27, 20], byMonth: [ - { label: 'Jan', values: [7, 5, 4, 2] }, - { label: 'Feb', values: [9, 6, 5, 3] }, - { label: 'Mar', values: [8, 6, 4, 2] }, - { label: 'Apr', values: [12, 8, 6, 4] }, - { label: 'May', values: [15, 11, 8, 5] }, - { label: 'Jun', values: [13, 9, 7, 4] }, - { label: 'Jul', values: [17, 12, 9, 6] }, + { id: 'jan', label: msg`Jan`, value: 12 }, + { id: 'feb', label: msg`Feb`, value: 16 }, + { id: 'mar', label: msg`Mar`, value: 14 }, + { id: 'apr', label: msg`Apr`, value: 22 }, + { id: 'may', label: msg`May`, value: 27 }, + { id: 'jun', label: msg`Jun`, value: 24 }, + { id: 'jul', label: msg`Jul`, value: 31 }, ], kpis: [ { - label: 'Revenue (YTD)', + id: 'revenue', + label: msg`Revenue (YTD)`, trendDirection: 'up', trendPercent: 12, value: '$1.2M', }, { - label: 'Avg deal size', + id: 'avg-deal-size', + label: msg`Avg deal size`, trendDirection: 'up', trendPercent: 5, value: '$9.4K', }, { - label: 'Win rate', + id: 'win-rate', + label: msg`Win rate`, trendDirection: 'down', trendPercent: 3, value: '34%', diff --git a/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-kpi.ts b/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-kpi.ts index 83cfdf57bb..cfa70f20ab 100644 --- a/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-kpi.ts +++ b/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-kpi.ts @@ -1,5 +1,8 @@ +import { type MessageDescriptor } from '@lingui/core'; + export type DashboardKpi = { - label: string; + id: string; + label: MessageDescriptor; trendDirection: 'down' | 'up'; trendPercent: number; value: string; diff --git a/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-month.ts b/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-month.ts index e8b7585a23..71af12a64c 100644 --- a/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-month.ts +++ b/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-month.ts @@ -1,4 +1,7 @@ +import { type MessageDescriptor } from '@lingui/core'; + export type DashboardMonth = { - label: string; - values: number[]; + id: string; + label: MessageDescriptor; + value: number; }; diff --git a/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-stage-tone.ts b/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-stage-tone.ts index ea278bce49..8f0ca3c7ee 100644 --- a/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-stage-tone.ts +++ b/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-stage-tone.ts @@ -1 +1,6 @@ -export type DashboardStageTone = 'blue' | 'orange' | 'purple' | 'turquoise'; +export type DashboardStageTone = + | 'purple' + | 'red' + | 'sky' + | 'turquoise' + | 'yellow'; diff --git a/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-stage.ts b/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-stage.ts index 9af4be26a0..1883e006fd 100644 --- a/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-stage.ts +++ b/packages/twenty-website/src/sections/product-feature/DashboardVisual/types/dashboard-stage.ts @@ -1,6 +1,10 @@ +import { type MessageDescriptor } from '@lingui/core'; + import { type DashboardStageTone } from './dashboard-stage-tone'; export type DashboardStage = { - label: string; + id: string; + label: MessageDescriptor; tone: DashboardStageTone; + value: number; }; diff --git a/packages/twenty-website/src/sections/product-feature/components/Tiles.tsx b/packages/twenty-website/src/sections/product-feature/components/Tiles.tsx index 3f1c904af4..cedc694320 100644 --- a/packages/twenty-website/src/sections/product-feature/components/Tiles.tsx +++ b/packages/twenty-website/src/sections/product-feature/components/Tiles.tsx @@ -74,7 +74,7 @@ const SpotlightVisual = styled.div` border: 1px solid ${color('black-20')}; border-radius: ${radius(2)}; margin: ${spacing(4)}; - min-height: 260px; + min-height: 300px; overflow: hidden; ${mediaUp('md')} {