updated colors and styling

This commit is contained in:
Lucas Oliveira 2025-09-22 10:13:00 -03:00
parent 57f3344641
commit a747f3712d
6 changed files with 237 additions and 231 deletions

View file

@ -3,7 +3,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react"; import * as React from "react";
const buttonVariants = cva( const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-70 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{ {
variants: { variants: {
variant: { variant: {
@ -11,7 +11,7 @@ const buttonVariants = cva(
destructive: destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90", "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: outline:
"border border-input hover:bg-muted hover:text-accent-foreground", "border border-input hover:bg-muted hover:text-accent-foreground disabled:bg-muted disabled:!border-none",
primary: primary:
"border bg-background text-secondary-foreground hover:bg-muted hover:shadow-sm", "border bg-background text-secondary-foreground hover:bg-muted hover:shadow-sm",
warning: warning:

View file

@ -34,6 +34,7 @@
--accent-emerald-foreground: 161.4 93.5% 30.4%; --accent-emerald-foreground: 161.4 93.5% 30.4%;
--accent-pink-foreground: 333.3 71.4% 50.6%; --accent-pink-foreground: 333.3 71.4% 50.6%;
--accent-amber-foreground: 26 90.5% 37.1%;
/* Status Colors */ /* Status Colors */
--status-red: #ef4444; --status-red: #ef4444;
@ -90,6 +91,7 @@
--accent-emerald-foreground: 158.1 64.4% 51.6%; --accent-emerald-foreground: 158.1 64.4% 51.6%;
--accent-pink-foreground: 328.6 85.5% 70.2%; --accent-pink-foreground: 328.6 85.5% 70.2%;
--accent-amber-foreground: 45.9 96.7% 64.5%;
/* Dark mode data type colors */ /* Dark mode data type colors */
--datatype-blue: 211.7 96.4% 78.4%; --datatype-blue: 211.7 96.4% 78.4%;

View file

@ -1,11 +1,11 @@
import { useState } from "react"; import { useState } from "react";
import { LabelInput } from "@/components/label-input"; import { LabelInput } from "@/components/label-input";
import IBMLogo from "@/components/logo/ibm-logo"; import IBMLogo from "@/components/logo/ibm-logo";
import { useDebouncedValue } from "@/lib/debounce";
import type { OnboardingVariables } from "../../api/mutations/useOnboardingMutation"; import type { OnboardingVariables } from "../../api/mutations/useOnboardingMutation";
import { useGetIBMModelsQuery } from "../../api/queries/useGetModelsQuery"; import { useGetIBMModelsQuery } from "../../api/queries/useGetModelsQuery";
import { useModelSelection } from "../hooks/useModelSelection"; import { useModelSelection } from "../hooks/useModelSelection";
import { useUpdateSettings } from "../hooks/useUpdateSettings"; import { useUpdateSettings } from "../hooks/useUpdateSettings";
import { useDebouncedValue } from "@/lib/debounce";
import { AdvancedOnboarding } from "./advanced"; import { AdvancedOnboarding } from "./advanced";
export function IBMOnboarding({ export function IBMOnboarding({
@ -96,19 +96,21 @@ export function IBMOnboarding({
onChange={(e) => setProjectId(e.target.value)} onChange={(e) => setProjectId(e.target.value)}
/> />
{isLoadingModels && ( {isLoadingModels && (
<p className="text-sm text-muted-foreground"> <p className="text-mmd text-muted-foreground">
Validating configuration... Validating configuration...
</p> </p>
)} )}
{modelsError && ( {modelsError && (
<p className="text-sm text-red-500"> <p className="text-mmd text-accent-amber-foreground">
Invalid configuration or connection failed Invalid configuration or connection failed
</p> </p>
)} )}
{modelsData && {modelsData &&
(modelsData.language_models?.length > 0 || (modelsData.language_models?.length > 0 ||
modelsData.embedding_models?.length > 0) && ( modelsData.embedding_models?.length > 0) && (
<p className="text-sm text-green-600">Configuration is valid</p> <p className="text-mmd text-accent-emerald-foreground">
Configuration is valid
</p>
)} )}
</div> </div>
<AdvancedOnboarding <AdvancedOnboarding

View file

@ -2,11 +2,11 @@ import { useState } from "react";
import { LabelInput } from "@/components/label-input"; import { LabelInput } from "@/components/label-input";
import { LabelWrapper } from "@/components/label-wrapper"; import { LabelWrapper } from "@/components/label-wrapper";
import OllamaLogo from "@/components/logo/ollama-logo"; import OllamaLogo from "@/components/logo/ollama-logo";
import { useDebouncedValue } from "@/lib/debounce";
import type { OnboardingVariables } from "../../api/mutations/useOnboardingMutation"; import type { OnboardingVariables } from "../../api/mutations/useOnboardingMutation";
import { useGetOllamaModelsQuery } from "../../api/queries/useGetModelsQuery"; import { useGetOllamaModelsQuery } from "../../api/queries/useGetModelsQuery";
import { useModelSelection } from "../hooks/useModelSelection"; import { useModelSelection } from "../hooks/useModelSelection";
import { useUpdateSettings } from "../hooks/useUpdateSettings"; import { useUpdateSettings } from "../hooks/useUpdateSettings";
import { useDebouncedValue } from "@/lib/debounce";
import { AdvancedOnboarding } from "./advanced"; import { AdvancedOnboarding } from "./advanced";
import { ModelSelector } from "./model-selector"; import { ModelSelector } from "./model-selector";
@ -70,62 +70,66 @@ export function OllamaOnboarding({
return ( return (
<> <>
<div className="space-y-1"> <div className="space-y-4">
<LabelInput <div className="space-y-1">
label="Ollama Endpoint" <LabelInput
helperText="The endpoint for your Ollama server." label="Ollama Endpoint"
id="api-endpoint" helperText="The endpoint for your Ollama server."
required id="api-endpoint"
placeholder="http://localhost:11434" required
value={endpoint} placeholder="http://localhost:11434"
onChange={(e) => setEndpoint(e.target.value)} value={endpoint}
/> onChange={(e) => setEndpoint(e.target.value)}
{isConnecting && ( />
<p className="text-sm text-muted-foreground"> {isConnecting && (
Connecting to Ollama server... <p className="text-mmd text-muted-foreground">
</p> Connecting to Ollama server...
)} </p>
{hasConnectionError && ( )}
<p className="text-sm text-red-500"> {hasConnectionError && (
Cannot connect to Ollama server. Please check the endpoint. <p className="text-mmd text-accent-amber-foreground">
</p> Cant reach Ollama at {debouncedEndpoint}. Update the endpoint or
)} start the server.
{hasNoModels && ( </p>
<p className="text-sm text-yellow-600"> )}
No models found. Please install some models on your Ollama server. {hasNoModels && (
</p> <p className="text-mmd text-accent-amber-foreground">
)} No models found. Please install some models on your Ollama server.
{isValidConnection && ( </p>
<p className="text-sm text-green-600">Connected successfully</p> )}
)} {isValidConnection && (
<p className="text-mmd text-accent-emerald-foreground">
Connected successfully
</p>
)}
</div>
<LabelWrapper
label="Embedding model"
helperText="The embedding model for your Ollama server."
id="embedding-model"
required={true}
>
<ModelSelector
options={embeddingModels}
icon={<OllamaLogo className="w-4 h-4" />}
value={embeddingModel}
onValueChange={setEmbeddingModel}
/>
</LabelWrapper>
<LabelWrapper
label="Language model"
helperText="The embedding model for your Ollama server."
id="embedding-model"
required={true}
>
<ModelSelector
options={languageModels}
icon={<OllamaLogo className="w-4 h-4" />}
value={languageModel}
onValueChange={setLanguageModel}
/>
</LabelWrapper>
</div> </div>
<LabelWrapper
label="Embedding model"
helperText="The embedding model for your Ollama server."
id="embedding-model"
required={true}
>
<ModelSelector
options={embeddingModels}
icon={<OllamaLogo className="w-4 h-4" />}
value={embeddingModel}
onValueChange={setEmbeddingModel}
/>
</LabelWrapper>
<LabelWrapper
label="Language model"
helperText="The embedding model for your Ollama server."
id="embedding-model"
required={true}
>
<ModelSelector
options={languageModels}
icon={<OllamaLogo className="w-4 h-4" />}
value={languageModel}
onValueChange={setLanguageModel}
/>
</LabelWrapper>
<AdvancedOnboarding <AdvancedOnboarding
sampleDataset={sampleDataset} sampleDataset={sampleDataset}
setSampleDataset={handleSampleDatasetChange} setSampleDataset={handleSampleDatasetChange}

View file

@ -1,11 +1,11 @@
import { useState } from "react"; import { useState } from "react";
import { LabelInput } from "@/components/label-input"; import { LabelInput } from "@/components/label-input";
import OpenAILogo from "@/components/logo/openai-logo"; import OpenAILogo from "@/components/logo/openai-logo";
import { useDebouncedValue } from "@/lib/debounce";
import type { OnboardingVariables } from "../../api/mutations/useOnboardingMutation"; import type { OnboardingVariables } from "../../api/mutations/useOnboardingMutation";
import { useGetOpenAIModelsQuery } from "../../api/queries/useGetModelsQuery"; import { useGetOpenAIModelsQuery } from "../../api/queries/useGetModelsQuery";
import { useModelSelection } from "../hooks/useModelSelection"; import { useModelSelection } from "../hooks/useModelSelection";
import { useUpdateSettings } from "../hooks/useUpdateSettings"; import { useUpdateSettings } from "../hooks/useUpdateSettings";
import { useDebouncedValue } from "@/lib/debounce";
import { AdvancedOnboarding } from "./advanced"; import { AdvancedOnboarding } from "./advanced";
export function OpenAIOnboarding({ export function OpenAIOnboarding({
@ -64,17 +64,21 @@ export function OpenAIOnboarding({
onChange={(e) => setApiKey(e.target.value)} onChange={(e) => setApiKey(e.target.value)}
/> />
{isLoadingModels && ( {isLoadingModels && (
<p className="text-sm text-muted-foreground">Validating API key...</p> <p className="text-mmd text-muted-foreground">
Validating API key...
</p>
)} )}
{modelsError && ( {modelsError && (
<p className="text-sm text-red-500"> <p className="text-mmd text-accent-amber-foreground">
Invalid API key or configuration Invalid API key
</p> </p>
)} )}
{modelsData && {modelsData &&
(modelsData.language_models?.length > 0 || (modelsData.language_models?.length > 0 ||
modelsData.embedding_models?.length > 0) && ( modelsData.embedding_models?.length > 0) && (
<p className="text-sm text-green-600">Configuration is valid</p> <p className="text-mmd text-accent-emerald-foreground">
API Key is valid
</p>
)} )}
</div> </div>
<AdvancedOnboarding <AdvancedOnboarding

View file

@ -14,170 +14,164 @@ const config = {
"./src/**/*.{ts,tsx}", "./src/**/*.{ts,tsx}",
], ],
theme: { theme: {
container: { container: {
center: true, center: true,
screens: { screens: {
'2xl': '1400px', "2xl": "1400px",
'3xl': '1500px' "3xl": "1500px",
} },
}, },
extend: { extend: {
screens: { screens: {
xl: '1200px', xl: "1200px",
'2xl': '1400px', "2xl": "1400px",
'3xl': '1500px' "3xl": "1500px",
}, },
keyframes: { keyframes: {
overlayShow: { overlayShow: {
from: { from: {
opacity: 0 opacity: 0,
}, },
to: { to: {
opacity: 1 opacity: 1,
} },
}, },
contentShow: { contentShow: {
from: { from: {
opacity: 0, opacity: 0,
transform: 'translate(-50%, -50%) scale(0.95)', transform: "translate(-50%, -50%) scale(0.95)",
clipPath: 'inset(50% 0)' clipPath: "inset(50% 0)",
}, },
to: { to: {
opacity: 1, opacity: 1,
transform: 'translate(-50%, -50%) scale(1)', transform: "translate(-50%, -50%) scale(1)",
clipPath: 'inset(0% 0)' clipPath: "inset(0% 0)",
} },
}, },
wiggle: { wiggle: {
'0%, 100%': { "0%, 100%": {
transform: 'scale(100%)' transform: "scale(100%)",
}, },
'50%': { "50%": {
transform: 'scale(120%)' transform: "scale(120%)",
} },
}, },
'accordion-down': { "accordion-down": {
from: { from: {
height: '0' height: "0",
}, },
to: { to: {
height: 'var(--radix-accordion-content-height)' height: "var(--radix-accordion-content-height)",
} },
}, },
'accordion-up': { "accordion-up": {
from: { from: {
height: 'var(--radix-accordion-content-height)' height: "var(--radix-accordion-content-height)",
}, },
to: { to: {
height: '0' height: "0",
} },
} },
}, },
animation: { animation: {
overlayShow: 'overlayShow 400ms cubic-bezier(0.16, 1, 0.3, 1)', overlayShow: "overlayShow 400ms cubic-bezier(0.16, 1, 0.3, 1)",
contentShow: 'contentShow 400ms cubic-bezier(0.16, 1, 0.3, 1)', contentShow: "contentShow 400ms cubic-bezier(0.16, 1, 0.3, 1)",
wiggle: 'wiggle 150ms ease-in-out 1', wiggle: "wiggle 150ms ease-in-out 1",
'accordion-down': 'accordion-down 0.2s ease-out', "accordion-down": "accordion-down 0.2s ease-out",
'accordion-up': 'accordion-up 0.2s ease-out' "accordion-up": "accordion-up 0.2s ease-out",
}, },
colors: { colors: {
border: 'hsl(var(--border))', border: "hsl(var(--border))",
input: 'hsl(var(--input))', input: "hsl(var(--input))",
ring: 'hsl(var(--ring))', ring: "hsl(var(--ring))",
background: 'hsl(var(--background))', background: "hsl(var(--background))",
foreground: 'hsl(var(--foreground))', foreground: "hsl(var(--foreground))",
primary: { primary: {
DEFAULT: 'hsl(var(--primary))', DEFAULT: "hsl(var(--primary))",
foreground: 'hsl(var(--primary-foreground))', foreground: "hsl(var(--primary-foreground))",
hover: 'hsl(var(--primary-hover))' hover: "hsl(var(--primary-hover))",
}, },
secondary: { secondary: {
DEFAULT: 'hsl(var(--secondary))', DEFAULT: "hsl(var(--secondary))",
foreground: 'hsl(var(--secondary-foreground))', foreground: "hsl(var(--secondary-foreground))",
hover: 'hsl(var(--secondary-hover))' hover: "hsl(var(--secondary-hover))",
}, },
destructive: { destructive: {
DEFAULT: 'hsl(var(--destructive))', DEFAULT: "hsl(var(--destructive))",
foreground: 'hsl(var(--destructive-foreground))' foreground: "hsl(var(--destructive-foreground))",
}, },
muted: { muted: {
DEFAULT: 'hsl(var(--muted))', DEFAULT: "hsl(var(--muted))",
foreground: 'hsl(var(--muted-foreground))' foreground: "hsl(var(--muted-foreground))",
}, },
accent: { accent: {
DEFAULT: 'hsl(var(--accent))', DEFAULT: "hsl(var(--accent))",
foreground: 'hsl(var(--accent-foreground))' foreground: "hsl(var(--accent-foreground))",
}, },
'accent-emerald-foreground': { "accent-emerald-foreground": {
DEFAULT: 'hsl(var(--accent-emerald-foreground))' DEFAULT: "hsl(var(--accent-emerald-foreground))",
}, },
'accent-pink-foreground': { "accent-pink-foreground": {
DEFAULT: 'hsl(var(--accent-pink-foreground))' DEFAULT: "hsl(var(--accent-pink-foreground))",
}, },
popover: { "accent-amber-foreground": {
DEFAULT: 'hsl(var(--popover))', DEFAULT: "hsl(var(--accent-amber-foreground))",
foreground: 'hsl(var(--popover-foreground))' },
}, popover: {
card: { DEFAULT: "hsl(var(--popover))",
DEFAULT: 'hsl(var(--card))', foreground: "hsl(var(--popover-foreground))",
foreground: 'hsl(var(--card-foreground))' },
}, card: {
'status-blue': 'var(--status-blue)', DEFAULT: "hsl(var(--card))",
'status-green': 'var(--status-green)', foreground: "hsl(var(--card-foreground))",
'status-red': 'var(--status-red)', },
'status-yellow': 'var(--status-yellow)', "status-blue": "var(--status-blue)",
'component-icon': 'var(--component-icon)', "status-green": "var(--status-green)",
'flow-icon': 'var(--flow-icon)', "status-red": "var(--status-red)",
'placeholder-foreground': 'hsl(var(--placeholder-foreground))', "status-yellow": "var(--status-yellow)",
'datatype-blue': { "component-icon": "var(--component-icon)",
DEFAULT: 'hsl(var(--datatype-blue))', "flow-icon": "var(--flow-icon)",
foreground: 'hsl(var(--datatype-blue-foreground))' "placeholder-foreground": "hsl(var(--placeholder-foreground))",
}, "datatype-blue": {
'datatype-yellow': { DEFAULT: "hsl(var(--datatype-blue))",
DEFAULT: 'hsl(var(--datatype-yellow))', foreground: "hsl(var(--datatype-blue-foreground))",
foreground: 'hsl(var(--datatype-yellow-foreground))' },
}, "datatype-yellow": {
'datatype-red': { DEFAULT: "hsl(var(--datatype-yellow))",
DEFAULT: 'hsl(var(--datatype-red))', foreground: "hsl(var(--datatype-yellow-foreground))",
foreground: 'hsl(var(--datatype-red-foreground))' },
}, "datatype-red": {
'datatype-emerald': { DEFAULT: "hsl(var(--datatype-red))",
DEFAULT: 'hsl(var(--datatype-emerald))', foreground: "hsl(var(--datatype-red-foreground))",
foreground: 'hsl(var(--datatype-emerald-foreground))' },
}, "datatype-emerald": {
'datatype-violet': { DEFAULT: "hsl(var(--datatype-emerald))",
DEFAULT: 'hsl(var(--datatype-violet))', foreground: "hsl(var(--datatype-emerald-foreground))",
foreground: 'hsl(var(--datatype-violet-foreground))' },
}, "datatype-violet": {
warning: { DEFAULT: "hsl(var(--datatype-violet))",
DEFAULT: 'hsl(var(--warning))', foreground: "hsl(var(--datatype-violet-foreground))",
foreground: 'hsl(var(--warning-foreground))' },
} warning: {
}, DEFAULT: "hsl(var(--warning))",
borderRadius: { foreground: "hsl(var(--warning-foreground))",
lg: 'var(--radius)', },
md: 'calc(var(--radius) - 2px)', },
sm: 'calc(var(--radius) - 4px)' borderRadius: {
}, lg: "var(--radius)",
fontFamily: { md: "calc(var(--radius) - 2px)",
sans: [ sm: "calc(var(--radius) - 4px)",
'var(--font-sans)', },
...fontFamily.sans fontFamily: {
], sans: ["var(--font-sans)", ...fontFamily.sans],
mono: [ mono: ["var(--font-mono)", ...fontFamily.mono],
'var(--font-mono)', chivo: ["var(--font-chivo)", ...fontFamily.sans],
...fontFamily.mono },
], fontSize: {
chivo: [ xxs: "11px",
'var(--font-chivo)', mmd: "13px",
...fontFamily.sans },
] },
},
fontSize: {
xxs: '11px',
mmd: '13px'
}
}
}, },
plugins: [ plugins: [
tailwindcssAnimate, tailwindcssAnimate,