Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions app/bots/BotNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ interface BotNavigationProps {
botTitle: string;
botEmoji: string;
botDescription?: string;
accentColor?: string;
menuItems: BotMenuItem[];
chatLink?: string;
sections?: boolean;
Expand All @@ -30,7 +29,6 @@ export const BotNavigation: React.FC<BotNavigationProps> = ({
botTitle,
botEmoji,
botDescription: _botDescription = '',
accentColor = 'blue',
menuItems: sectionMenuItems,
chatLink,
sections = true,
Expand Down Expand Up @@ -79,7 +77,6 @@ export const BotNavigation: React.FC<BotNavigationProps> = ({
currentBotSlug={botSlug}
currentBotTitle={botTitle}
currentBotEmoji={botEmoji}
accentColor={accentColor}
/>
</div>

Expand Down
7 changes: 2 additions & 5 deletions components/navigation/BotSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,23 @@ import { Popover, Transition, Portal } from '@headlessui/react';
import Link from 'next/link';
import bots from '@/data/bots';
import { getBotPath } from '@/lib/routes';
import { BOT_SWITCHER_COLORS, type CustomBotAccentColor } from '@/lib/config/colors';
import { BRAND_SWITCHER } from '@/lib/config/colors';

interface BotSwitcherProps {
currentBotSlug: string;
currentBotTitle: string;
currentBotEmoji: string;
accentColor?: string;
}

export function BotSwitcher({
currentBotSlug,
currentBotTitle,
currentBotEmoji,
accentColor = 'blue',
}: BotSwitcherProps) {
const buttonRef = useRef<HTMLButtonElement>(null);
// Filter out current bot and bots without nav config
const otherBots = bots.filter((bot) => bot.slug !== currentBotSlug && bot.nav);
const colors =
BOT_SWITCHER_COLORS[accentColor as CustomBotAccentColor] || BOT_SWITCHER_COLORS.blue;
const colors = BRAND_SWITCHER;

// Get button position for portal positioning
const getDropdownStyle = () => {
Expand Down
18 changes: 5 additions & 13 deletions components/shared/demo/DemoChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@

import { useState, useRef, useEffect, type FC, type FormEvent, type KeyboardEvent } from 'react';
import type { ChatMessage, DemoOutputConfig } from '@/lib/demo/types';
import type { BotAccentColor } from '@/types/bot';
import {
ACCENT_BUTTON_CLASSES,
ACCENT_FOCUS_RING_CLASSES,
ACCENT_STARTER_CLASSES,
} from '@/lib/config/colors';
import { BRAND_BUTTON, BRAND_FOCUS_RING, BRAND_STARTER } from '@/lib/config/colors';
import { DemoMessage, DemoDisclaimer } from './DemoMessage';

interface DemoChatProps {
Expand All @@ -16,7 +11,6 @@ interface DemoChatProps {
isLoading: boolean;
starterQuestions: string[];
botIcon: string;
accentColor: BotAccentColor;
outputConfig: DemoOutputConfig;
}

Expand All @@ -42,15 +36,14 @@ export const DemoChat: FC<DemoChatProps> = ({
isLoading,
starterQuestions,
botIcon,
accentColor,
outputConfig,
}) => {
const [input, setInput] = useState('');
const messagesEndRef = useRef<HTMLDivElement>(null);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const buttonClass = ACCENT_BUTTON_CLASSES[accentColor];
const focusClass = ACCENT_FOCUS_RING_CLASSES[accentColor];
const starterClass = ACCENT_STARTER_CLASSES[accentColor];
const buttonClass = BRAND_BUTTON;
const focusClass = BRAND_FOCUS_RING;
const starterClass = BRAND_STARTER;

// Show starter questions only when there's just the welcome message
const showStarters = messages.length === 1 && messages[0].role === 'assistant';
Expand Down Expand Up @@ -109,7 +102,6 @@ export const DemoChat: FC<DemoChatProps> = ({
key={message.id}
message={message}
botIcon={botIcon}
accentColor={accentColor}
outputConfig={outputConfig}
/>
))}
Expand Down Expand Up @@ -142,7 +134,7 @@ export const DemoChat: FC<DemoChatProps> = ({
{/* Disclaimer */}
{outputConfig.showDisclaimer && (
<div className="px-4 pb-2">
<DemoDisclaimer config={outputConfig} accentColor={accentColor} />
<DemoDisclaimer config={outputConfig} />
</div>
)}

Expand Down
7 changes: 2 additions & 5 deletions components/shared/demo/DemoContextPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,23 @@

import { useState, type FC } from 'react';
import type { IntakeQuestion, IntakeResponses, UploadedFile } from '@/lib/demo/types';
import type { BotAccentColor } from '@/types/bot';
import { ACCENT_CONTEXT_PANEL_CLASSES } from '@/lib/config/colors';
import { BRAND_CONTEXT_PANEL } from '@/lib/config/colors';

interface DemoContextPanelProps {
intakeQuestions: IntakeQuestion[];
intakeResponses: IntakeResponses;
files: UploadedFile[];
onReset: () => void;
accentColor: BotAccentColor;
}

export const DemoContextPanel: FC<DemoContextPanelProps> = ({
intakeQuestions,
intakeResponses,
files,
onReset,
accentColor,
}) => {
const [isExpanded, setIsExpanded] = useState(false);
const colors = ACCENT_CONTEXT_PANEL_CLASSES[accentColor];
const colors = BRAND_CONTEXT_PANEL;

// Filter to only show answered questions
const answeredQuestions = intakeQuestions.filter((q) => {
Expand Down
7 changes: 2 additions & 5 deletions components/shared/demo/DemoFileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import { useState, useRef, type FC, type DragEvent, type ChangeEvent } from 'react';
import type { FileCategory, UploadedFile } from '@/lib/demo/types';
import type { BotAccentColor } from '@/types/bot';
import { ACCENT_DROPZONE_CLASSES } from '@/lib/config/colors';
import { BRAND_DROPZONE } from '@/lib/config/colors';
import { formatBytes } from '@/lib/format';

interface DemoFileUploadProps {
Expand All @@ -12,7 +11,6 @@ interface DemoFileUploadProps {
onUpload: (files: File[]) => Promise<void>;
onRemove: (fileId: string) => void;
isUploading: boolean;
accentColor: BotAccentColor;
}

function getStatusIcon(status: UploadedFile['status']) {
Expand Down Expand Up @@ -95,11 +93,10 @@ export const DemoFileUpload: FC<DemoFileUploadProps> = ({
onUpload,
onRemove,
isUploading,
accentColor,
}) => {
const [isDragging, setIsDragging] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
const colors = ACCENT_DROPZONE_CLASSES[accentColor];
const colors = BRAND_DROPZONE;

// Get all accepted file types from categories
const acceptedTypes = Array.from(new Set(categories.flatMap((c) => c.acceptedTypes))).join(',');
Expand Down
15 changes: 4 additions & 11 deletions components/shared/demo/DemoIntake.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@

import { useState, type FC, type FormEvent } from 'react';
import type { IntakeQuestion, IntakeResponses } from '@/lib/demo/types';
import type { BotAccentColor } from '@/types/bot';
import {
ACCENT_BUTTON_CLASSES,
ACCENT_FOCUS_RING_CLASSES,
ACCENT_CHECKBOX_CLASSES,
} from '@/lib/config/colors';
import { BRAND_BUTTON, BRAND_FOCUS_RING, BRAND_CHECKBOX } from '@/lib/config/colors';

interface DemoIntakeProps {
questions: IntakeQuestion[];
responses: IntakeResponses;
onUpdate: (questionId: string, value: string | string[]) => void;
onStart: () => void;
accentColor: BotAccentColor;
icon: string;
botName: string;
}
Expand All @@ -24,14 +18,13 @@ export const DemoIntake: FC<DemoIntakeProps> = ({
responses,
onUpdate,
onStart,
accentColor,
icon,
botName,
}) => {
const [showAdvanced, setShowAdvanced] = useState(false);
const buttonClass = ACCENT_BUTTON_CLASSES[accentColor];
const focusClass = ACCENT_FOCUS_RING_CLASSES[accentColor];
const checkboxClass = ACCENT_CHECKBOX_CLASSES[accentColor];
const buttonClass = BRAND_BUTTON;
const focusClass = BRAND_FOCUS_RING;
const checkboxClass = BRAND_CHECKBOX;

const essentialQuestions = questions.filter((q) => q.phase === 'essential');
const advancedQuestions = questions.filter((q) => q.phase === 'advanced');
Expand Down
18 changes: 5 additions & 13 deletions components/shared/demo/DemoMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,17 @@

import type { FC } from 'react';
import type { ChatMessage, DemoOutputConfig } from '@/lib/demo/types';
import type { BotAccentColor } from '@/types/bot';
import { ACCENT_MESSAGE_CLASSES } from '@/lib/config/colors';
import { BRAND_MESSAGE } from '@/lib/config/colors';

interface DemoMessageProps {
message: ChatMessage;
botIcon: string;
accentColor: BotAccentColor;
outputConfig: DemoOutputConfig;
}

export const DemoMessage: FC<DemoMessageProps> = ({
message,
botIcon,
accentColor,
outputConfig,
}) => {
export const DemoMessage: FC<DemoMessageProps> = ({ message, botIcon, outputConfig }) => {
const isUser = message.role === 'user';
const colors = ACCENT_MESSAGE_CLASSES[accentColor];
const colors = BRAND_MESSAGE;

return (
<div className={`flex gap-3 ${isUser ? 'justify-end' : 'justify-start'}`}>
Expand Down Expand Up @@ -100,13 +93,12 @@ export const DemoMessage: FC<DemoMessageProps> = ({
// Disclaimer component shown at bottom of chat
interface DemoDisclaimerProps {
config: DemoOutputConfig;
accentColor: BotAccentColor;
}

export const DemoDisclaimer: FC<DemoDisclaimerProps> = ({ config, accentColor }) => {
export const DemoDisclaimer: FC<DemoDisclaimerProps> = ({ config }) => {
if (!config.showDisclaimer || !config.disclaimerText) return null;

const colors = ACCENT_MESSAGE_CLASSES[accentColor];
const colors = BRAND_MESSAGE;

return (
<div className={`${colors.bg} ${colors.border} border rounded-lg p-3 text-xs text-gray-600`}>
Expand Down
8 changes: 3 additions & 5 deletions components/shared/demo/DemoProgress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,19 @@

import type { FC } from 'react';
import type { DemoStep } from '@/lib/demo/types';
import type { BotAccentColor } from '@/types/bot';
import { ACCENT_PROGRESS_CLASSES } from '@/lib/config/colors';
import { BRAND_PROGRESS } from '@/lib/config/colors';

interface DemoProgressProps {
currentStep: DemoStep;
accentColor: BotAccentColor;
}

const steps: { id: DemoStep; label: string; number: number }[] = [
{ id: 'intake', label: 'Tell us about your needs', number: 1 },
{ id: 'chat', label: 'Chat with your assistant', number: 2 },
];

export const DemoProgress: FC<DemoProgressProps> = ({ currentStep, accentColor }) => {
const colors = ACCENT_PROGRESS_CLASSES[accentColor];
export const DemoProgress: FC<DemoProgressProps> = ({ currentStep }) => {
const colors = BRAND_PROGRESS;
const currentIndex = steps.findIndex((s) => s.id === currentStep);

return (
Expand Down
6 changes: 1 addition & 5 deletions components/shared/demo/DemoSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const DemoSection: FC<DemoSectionProps> = ({ botSlug, className = '' }) =
return (
<div className={`${className}`}>
{/* Progress indicator */}
<DemoProgress currentStep={state.step} accentColor={config.accentColor} />
<DemoProgress currentStep={state.step} />

{/* Intake step */}
{state.step === 'intake' && (
Expand All @@ -49,7 +49,6 @@ export const DemoSection: FC<DemoSectionProps> = ({ botSlug, className = '' }) =
responses={state.intakeResponses}
onUpdate={state.updateIntake}
onStart={state.startChat}
accentColor={config.accentColor}
icon={config.icon}
botName={botName}
/>
Expand All @@ -67,7 +66,6 @@ export const DemoSection: FC<DemoSectionProps> = ({ botSlug, className = '' }) =
isLoading={state.isLoading}
starterQuestions={config.starterQuestions}
botIcon={config.icon}
accentColor={config.accentColor}
outputConfig={config.outputConfig}
/>
</div>
Expand All @@ -80,7 +78,6 @@ export const DemoSection: FC<DemoSectionProps> = ({ botSlug, className = '' }) =
intakeResponses={state.intakeResponses}
files={state.files}
onReset={state.reset}
accentColor={config.accentColor}
/>

{/* File upload */}
Expand Down Expand Up @@ -108,7 +105,6 @@ export const DemoSection: FC<DemoSectionProps> = ({ botSlug, className = '' }) =
onUpload={state.uploadFiles}
onRemove={state.removeFile}
isUploading={state.isUploading}
accentColor={config.accentColor}
/>
</div>
)}
Expand Down
33 changes: 33 additions & 0 deletions lib/config/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,39 @@ const ACCENT_CLASS_SETS: Record<CustomBotAccentColor, AccentClasses> = {
* app/globals.css. The per-colour sets below remain for user-created custom
* bots, where accent_color is a real column the owner chooses.
*/
// ---------------------------------------------------------------------------
// Brand equivalents of the per-colour maps above.
//
// First-party surfaces (the six bots, their demo, the bot switcher) use these.
// The per-colour maps remain for user-created bots, where the owner picks
// accent_color and it is stored on the row.
// ---------------------------------------------------------------------------

export const BRAND_BUTTON = 'bg-action hover:bg-action-hover focus:ring-action';
export const BRAND_FOCUS_RING = 'focus:border-action focus:ring-action';
export const BRAND_STARTER = 'border-edge hover:border-action hover:bg-action-tint text-action';
export const BRAND_CHECKBOX = 'text-action focus:ring-action';
export const BRAND_PROGRESS = {
active: 'border-action bg-action-tint',
completed: 'bg-action border-action',
text: 'text-action',
};
export const BRAND_MESSAGE = { bg: 'bg-action-tint', border: 'border-edge' };
export const BRAND_DROPZONE = {
border: 'border-edge',
bg: 'bg-action-tint',
text: 'text-action',
};
export const BRAND_CONTEXT_PANEL = {
bg: 'bg-action-tint',
text: 'text-action',
border: 'border-edge',
};
export const BRAND_SWITCHER = {
button: 'hover:bg-action-tint',
active: 'bg-action-tint text-action',
};

export const BRAND_ACCENT: AccentClasses = {
primary: 'bg-action',
text: 'text-action',
Expand Down
Loading
Loading