Skip to content

Commit 28711f6

Browse files
authored
Merge pull request #31 from tinybirdco/design-fixes
Design fixes
2 parents 9e0be33 + 743db90 commit 28711f6

File tree

8 files changed

+179
-32
lines changed

8 files changed

+179
-32
lines changed

dashboard/ai-analytics/src/app/components/CustomBarList.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,16 @@ export default function CustomBarList({
8080
<div className="flex items-center w-full py-1">
8181
<div className="flex items-center min-w-0 flex-1">
8282
{item.icon && (
83-
<div className="mr-2.5 flex-shrink-0">
83+
<div className="mr-2.5 flex-shrink-0 color-[#C6C6C6]">
8484
{item.icon}
8585
</div>
8686
)}
87-
<p className="truncate text-sm text-tremor-default text-tremor-content dark:text-dark-tremor-content" style={{ fontFamily: 'var(--font-family-base)' }}>
87+
<p className="truncate small-font" style={{ fontFamily: 'var(--font-family-base)' }}>
8888
{item.name}
8989
</p>
9090
</div>
91-
<p className={`flex-shrink-0 text-right text-sm ${
92-
isSelected ? 'text-indigo-600 dark:text-indigo-400' : 'text-tremor-default dark:text-dark-tremor-default text-tremor-content dark:text-dark-tremor-content'
91+
<p className={`flex-shrink-0 text-right ${
92+
isSelected ? 'text-indigo-600 dark:text-indigo-400' : 'small-font'
9393
}`}>
9494
{valueFormatter(item.value)}
9595
</p>
@@ -115,7 +115,7 @@ export default function CustomBarList({
115115
style={{ boxShadow: 'none' }}
116116
>
117117
<div className="flex items-center justify-between mb-4">
118-
<h3 className="text-sm text-tremor-default text-tremor-content dark:text-dark-tremor-content" style={{ fontFamily: 'var(--font-family-base)' }}>Cost Breakdown</h3>
118+
<h3 className="small-font" style={{ fontFamily: 'var(--font-family-base)' }}>Cost Breakdown</h3>
119119
<p className="text-tremor-metric">
120120
{valueFormatter(totalValue)}
121121
</p>
@@ -143,6 +143,7 @@ export default function CustomBarList({
143143
static={true}
144144
className="z-[100]"
145145
>
146+
<div className="fixed inset-0 bg-[#0A0A0A] bg-opacity-80" />
146147
<DialogPanel className="!bg-[#262626] flex flex-col relative z-10 rounded-none p-0" style={{ width: '575px', minWidth: '575px' }}>
147148
{/* Header */}
148149
<div className="flex items-center justify-between p-4 pb-0">

dashboard/ai-analytics/src/app/components/DataTable.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ export default function DataTable({
314314

315315
return (
316316
<div className="flex flex-col h-full relative">
317-
{/* Content container with conditional blur */}
318-
<div className={`flex-1 overflow-auto min-h-0 transition-all duration-300 ${selectedMessage ? 'blur-sm' : ''}`}>
317+
{/* Content container without blur */}
318+
<div className="flex-1 overflow-auto min-h-0">
319319
<div className="min-w-[1024px]">
320320
<Table className="font-['Roboto'] text-[#F4F4F4]">
321321
<TableHead className="sticky top-0 z-10">
@@ -389,7 +389,7 @@ export default function DataTable({
389389
{/* Semi-transparent overlay */}
390390
{selectedMessage && (
391391
<div
392-
className="fixed inset-0 bg-black bg-opacity-30 z-40 backdrop-blur-sm"
392+
className="fixed inset-0 bg-[#0A0A0A] bg-opacity-80 z-40"
393393
onClick={handleCloseDetail}
394394
/>
395395
)}

dashboard/ai-analytics/src/app/components/DateRangeSelector.tsx

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,18 +244,21 @@ export default function DateRangeSelector({ onDateRangeChange }: DateRangeSelect
244244
// Format as "Jan 1 - Jan 15" for custom date ranges
245245
setSelectedRange(`${format(start, 'MMM d')} - ${format(end, 'MMM d')}`);
246246
setIsPredefinedRange(false);
247-
248247
}, []);
249248

249+
// Handle calendar popover close
250+
const handleCalendarPopoverOpenChange = useCallback((open: boolean) => {
251+
setCalendarOpen(open);
252+
if (!open && dateRange.start && dateRange.end) {
253+
updateUrlParams(dateRange.start, dateRange.end);
254+
}
255+
}, [dateRange, updateUrlParams]);
256+
250257
// Memoize the open/close handlers to prevent recreation
251258
const handleRangePopoverOpenChange = useCallback((open: boolean) => {
252259
setIsOpen(open);
253260
}, []);
254261

255-
const handleCalendarPopoverOpenChange = useCallback((open: boolean) => {
256-
setCalendarOpen(open);
257-
}, []);
258-
259262
return (
260263
<div className={`date-range-selector ${isOpen || calendarOpen ? 'ring-1 ring-white' : ''}`}>
261264
<div className="date-range-content">
@@ -312,7 +315,18 @@ export default function DateRangeSelector({ onDateRangeChange }: DateRangeSelect
312315
</Popover>
313316

314317
{/* Date Range Text */}
315-
<span className="date-range-text flex-grow">
318+
<span
319+
className="date-range-text flex-grow cursor-pointer"
320+
onClick={() => {
321+
if (isPredefinedRange) {
322+
setIsOpen(true);
323+
setCalendarOpen(false);
324+
} else {
325+
setCalendarOpen(true);
326+
setIsOpen(false);
327+
}
328+
}}
329+
>
316330
{selectedRange || 'Select date range'}
317331
</span>
318332

@@ -341,7 +355,9 @@ export default function DateRangeSelector({ onDateRangeChange }: DateRangeSelect
341355
{dateRangeOptions.map((option) => (
342356
<div
343357
key={option.label}
344-
className="cursor-pointer dropdown-font text-[#C6C6C6] hover:text-white hover:bg-[#3D3D3D] transition-colors duration-150 ease-in-out"
358+
className={`cursor-pointer dropdown-font hover:text-white hover:bg-[#3D3D3D] transition-colors duration-150 ease-in-out ${
359+
selectedRange === option.label ? '!text-white bg-[#3D3D3D]' : 'text-[#C6C6C6]'
360+
}`}
345361
onClick={() => handleRangeSelect(option)}
346362
>
347363
<span className="block px-4 py-4">

dashboard/ai-analytics/src/app/components/TabbedPane.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,21 @@ if (typeof document !== 'undefined') {
3636
// Custom OpenAI Icon
3737
const OpenAIIcon = () => (
3838
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" className="text-green-500">
39-
<path d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" fill="#6b7280"/>
39+
<path d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z" fill="#C6C6C6"/>
4040
</svg>
4141
);
4242

4343
// Custom Anthropic Icon
4444
const AnthropicIcon = () => (
4545
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" className="text-purple-500">
46-
<path d="M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zm-7.258 0h3.767L16.906 20h-3.674l-1.343-3.461H5.017l-1.344 3.46H0L6.57 3.522zm4.132 9.959L8.453 7.687 6.205 13.48H10.7z" fill="#6b7280"/>
46+
<path d="M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zm-7.258 0h3.767L16.906 20h-3.674l-1.343-3.461H5.017l-1.344 3.46H0L6.57 3.522zm4.132 9.959L8.453 7.687 6.205 13.48H10.7z" fill="#C6C6C6"/>
4747
</svg>
4848
);
4949

5050
// Custom Google AI Icon
5151
const GoogleAIIcon = () => (
5252
<svg viewBox="0 0 24 24" width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" className="text-blue-500">
53-
<path d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z" fill="#6b7280"/>
53+
<path d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z" fill="#C6C6C6"/>
5454
</svg>
5555
);
5656

dashboard/ai-analytics/src/app/components/TopBar.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { UserButton, SignedIn, SignedOut } from "@clerk/nextjs";
55
import FilterChips from './FilterChips';
66
import { useRef, useState } from 'react';
77
import DateRangeSelector from './DateRangeSelector';
8-
import { FilterIcon, SettingsIcon, SignInIcon } from './icons';
8+
import { SettingsIcon, SignInIcon } from './icons';
99
import { useModal } from '../context/ModalContext';
1010
import { useApiKeyStore } from '@/stores/apiKeyStore';
1111
import ApiKeyInput from './ApiKeyInput';
@@ -137,7 +137,7 @@ export default function TopBar({ selections, onRemoveFilter }: TopBarProps) {
137137
<span className="font-roboto text-base font-normal">
138138
AI Cost Calculator
139139
</span>
140-
<FilterIcon fill="currentColor" />
140+
<Sparkles className="h-4 w-4" />
141141
</button>
142142
<div className="relative w-[288px]">
143143
<input
@@ -203,6 +203,7 @@ export default function TopBar({ selections, onRemoveFilter }: TopBarProps) {
203203
onClose={() => setIsSettingsOpen(false)}
204204
static={true}
205205
>
206+
<div className="fixed inset-0 bg-[#0A0A0A] bg-opacity-80" />
206207
<DialogPanel className="max-w-md">
207208
<div className="p-6">
208209
<div className="flex items-center justify-between mb-6">
@@ -223,10 +224,16 @@ export default function TopBar({ selections, onRemoveFilter }: TopBarProps) {
223224
</Dialog>
224225

225226
{/* Sign In Modal */}
226-
<SignInModal
227-
isOpen={isSignInOpen}
227+
<Dialog
228+
open={isSignInOpen}
228229
onClose={() => setIsSignInOpen(false)}
229-
/>
230+
static={true}
231+
>
232+
<SignInModal
233+
isOpen={isSignInOpen}
234+
onClose={() => setIsSignInOpen(false)}
235+
/>
236+
</Dialog>
230237
</div>
231238
);
232239
}

dashboard/ai-analytics/src/app/containers/DataTableContainer.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import { useState, useEffect } from 'react';
55
import DataTable from '../components/DataTable';
66
import { useLLMMessages } from '@/hooks/useTinybirdData';
7-
import { Search } from 'lucide-react';
7+
import { Search, Sparkles } from 'lucide-react';
88

99
interface DataTableContainerProps {
1010
filters: Record<string, string>;
@@ -71,10 +71,16 @@ export default function DataTableContainer({ filters, isLoading = false }: DataT
7171
<div className="p-4">
7272
<form onSubmit={handleSearch} className="flex gap-2">
7373
<div className="relative flex-grow">
74+
<button
75+
type="submit"
76+
className="absolute inset-y-0 left-0 flex items-center px-4 text-white hover:text-white"
77+
>
78+
<Search className="w-4 h-4" />
79+
</button>
7480
<input
7581
type="text"
7682
placeholder="Search conversations semantically..."
77-
className="w-full h-[48px] px-4 pr-12 py-2 bg-tremor-background-subtle dark:bg-dark-tremor-background-subtle focus:outline-none focus:ring-1 focus:ring-white placeholder:text-tremor-content dark:placeholder:text-dark-tremor-content placeholder:text-sm font-['Roboto'] dark:placeholder:text-[#8D8D8D]"
83+
className="w-full h-[48px] px-4 pl-10 pr-12 py-2 bg-tremor-background-subtle dark:bg-dark-tremor-background-subtle focus:outline-none focus:ring-1 focus:ring-white placeholder:text-tremor-content dark:placeholder:text-dark-tremor-content placeholder:text-sm font-['Roboto'] dark:placeholder:text-[#8D8D8D] placeholder:focus:opacity-0"
7884
value={searchInput}
7985
onChange={(e) => setSearchInput(e.target.value)}
8086
onKeyDown={(e) => {
@@ -86,9 +92,9 @@ export default function DataTableContainer({ filters, isLoading = false }: DataT
8692
/>
8793
<button
8894
type="submit"
89-
className="absolute inset-y-0 right-0 flex items-center px-3 text-white hover:text-white"
95+
className="absolute inset-y-0 right-0 flex items-center px-4 text-white hover:text-white"
9096
>
91-
<Search className="w-5 h-5" />
97+
<Sparkles className={`w-4 h-4 search-input-right-icon ${isGeneratingEmbedding ? 'animate' : ''}`} />
9298
</button>
9399
</div>
94100
{/* {searchText && (

dashboard/ai-analytics/src/app/globals.css

Lines changed: 111 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,27 @@ body {
195195
padding: 0;
196196
}
197197

198-
.filter-input::placeholder {
199-
color: #F4F4F4;
200-
opacity: 0.5;
198+
/* Apply placeholder styles to all input types */
199+
input::placeholder,
200+
textarea::placeholder,
201+
select::placeholder {
202+
color: #C6C6C6 !important;
203+
opacity: 1;
204+
font-family: var(--font-family-base) !important;
205+
font-size: var(--font-size-sm) !important;
206+
line-height: var(--line-height-sm) !important;
207+
}
208+
209+
/* Ensure placeholder styles work in Firefox */
210+
::-moz-placeholder {
211+
color: #C6C6C6 !important;
212+
opacity: 1;
213+
}
214+
215+
/* Ensure placeholder styles work in IE */
216+
:-ms-input-placeholder {
217+
color: #C6C6C6 !important;
218+
opacity: 1;
201219
}
202220

203221
.filter-input:focus {
@@ -224,10 +242,18 @@ body {
224242
flex: none;
225243
order: 0;
226244
flex-grow: 0;
245+
transition: all 0.2s ease;
246+
border: 1px solid transparent;
227247
}
228248

229249
.settings-button:hover {
230-
background: rgba(53, 53, 53, 0.9);
250+
background: transparent;
251+
border: 1px solid var(--accent);
252+
color: var(--accent);
253+
}
254+
255+
.settings-button:hover * {
256+
color: var(--accent);
231257
}
232258

233259
/* Tremor Tab styles override */
@@ -270,6 +296,13 @@ body {
270296
background: transparent !important;
271297
}
272298

299+
/* Tremor Chart Axis Labels */
300+
.recharts-text tspan {
301+
fill: #C6C6C6 !important;
302+
color: #C6C6C6 !important;
303+
font-size: 12px !important;
304+
}
305+
273306
/* Bar Chart styles */
274307
.tremor-BarChart rect[role="graphics-symbol"] {
275308
stroke: #000000;
@@ -285,4 +318,78 @@ body {
285318
::-moz-selection {
286319
background-color: var(--accent); /* Your accent color */
287320
color: var(--background);
321+
}
322+
323+
/* Search Input Styles */
324+
.search-input-container {
325+
position: relative;
326+
width: 288px;
327+
}
328+
329+
.search-input {
330+
width: 100%;
331+
height: 48px;
332+
padding: 0 8px;
333+
background: var(--tremor-background-subtle);
334+
border: 1px solid transparent;
335+
border-radius: 0px;
336+
color: var(--tremor-content);
337+
font-family: 'Roboto', sans-serif;
338+
font-size: 14px;
339+
transition: all 0.2s ease;
340+
}
341+
342+
.search-input:focus {
343+
outline: none;
344+
border-color: var(--accent);
345+
}
346+
347+
.search-input::placeholder {
348+
color: var(--tremor-content);
349+
opacity: 0.7;
350+
transition: opacity 0.2s ease;
351+
}
352+
353+
.search-input:focus::placeholder {
354+
opacity: 0;
355+
}
356+
357+
.search-input-left-icon {
358+
position: absolute;
359+
left: 8px;
360+
top: 50%;
361+
transform: translateY(-50%);
362+
color: var(--tremor-content);
363+
opacity: 0.7;
364+
}
365+
366+
.search-input-right-icon {
367+
position: absolute;
368+
right: 16px;
369+
top: 50%;
370+
transform: translateY(-50%);
371+
color: var(--tremor-content);
372+
transition: all 0.2s ease;
373+
}
374+
375+
.search-input:focus ~ .search-input-right-icon {
376+
color: var(--accent);
377+
opacity: 1;
378+
}
379+
380+
.search-input-right-icon.animate {
381+
animation: sparkle 1s ease-in-out infinite;
382+
color: var(--accent);
383+
}
384+
385+
@keyframes sparkle {
386+
0% {
387+
opacity: 0.7;
388+
}
389+
50% {
390+
opacity: 1;
391+
}
392+
100% {
393+
opacity: 0.7;
394+
}
288395
}

dashboard/ai-analytics/tailwind.config.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module.exports = {
3434
},
3535
content: {
3636
subtle: '#4b5563', // gray-600
37-
DEFAULT: '#6b7280', // gray-500
37+
DEFAULT: '#C6C6C6', // gray-500
3838
emphasis: '#e5e7eb', // gray-200
3939
strong: '#f9fafb', // gray-50
4040
inverted: '#000000', // black
@@ -77,6 +77,16 @@ module.exports = {
7777
}],
7878
'tremor-tab': ['14px', { lineHeight: '20px' }], // custom tab font size
7979
},
80+
// Add Tremor chart styles
81+
tremor: {
82+
chart: {
83+
axis: {
84+
label: {
85+
color: '#C6C6C6',
86+
},
87+
},
88+
},
89+
},
8090
},
8191
},
8292
safelist: [

0 commit comments

Comments
 (0)