UI update with sidebar and settings tabs (#3288)
Co-authored-by: Nahiyan Khan <nahiyan@squareup.com> Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Co-authored-by: Lily Delalande <119957291+lily-de@users.noreply.github.com> Co-authored-by: Spence <spencrmartin@gmail.com> Co-authored-by: spencrmartin <spencermartin@squareup.com> Co-authored-by: Judson Stephenson <Jud@users.noreply.github.com> Co-authored-by: Max Novich <mnovich@squareup.com> Co-authored-by: Best Codes <106822363+The-Best-Codes@users.noreply.github.com> Co-authored-by: caroline-a-mckenzie <cmckenzie@squareup.com> Co-authored-by: Michael Neale <michael.neale@gmail.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import React, { createContext, useContext, ReactNode } from 'react';
|
||||
import { ChatType } from '../components/BaseChat';
|
||||
import { generateSessionId } from '../sessions';
|
||||
import { Recipe } from '../recipe';
|
||||
import { useDraftContext } from './DraftContext';
|
||||
|
||||
interface ChatContextType {
|
||||
chat: ChatType;
|
||||
setChat: (chat: ChatType) => void;
|
||||
resetChat: () => void;
|
||||
hasActiveSession: boolean;
|
||||
setRecipeConfig: (recipe: Recipe | null) => void;
|
||||
clearRecipeConfig: () => void;
|
||||
// Draft functionality
|
||||
draft: string;
|
||||
setDraft: (draft: string) => void;
|
||||
clearDraft: () => void;
|
||||
// Context identification
|
||||
contextKey: string; // 'hub' or 'pair-{sessionId}'
|
||||
}
|
||||
|
||||
const ChatContext = createContext<ChatContextType | undefined>(undefined);
|
||||
|
||||
interface ChatProviderProps {
|
||||
children: ReactNode;
|
||||
chat: ChatType;
|
||||
setChat: (chat: ChatType) => void;
|
||||
contextKey?: string; // Optional context key, defaults to 'hub'
|
||||
}
|
||||
|
||||
export const ChatProvider: React.FC<ChatProviderProps> = ({
|
||||
children,
|
||||
chat,
|
||||
setChat,
|
||||
contextKey = 'hub',
|
||||
}) => {
|
||||
const draftContext = useDraftContext();
|
||||
|
||||
// Draft functionality using the app-level DraftContext
|
||||
const draft = draftContext.getDraft(contextKey);
|
||||
|
||||
const setDraft = (newDraft: string) => {
|
||||
draftContext.setDraft(contextKey, newDraft);
|
||||
};
|
||||
|
||||
const clearDraft = () => {
|
||||
draftContext.clearDraft(contextKey);
|
||||
};
|
||||
|
||||
const resetChat = () => {
|
||||
const newSessionId = generateSessionId();
|
||||
setChat({
|
||||
id: newSessionId,
|
||||
title: 'New Chat',
|
||||
messages: [],
|
||||
messageHistoryIndex: 0,
|
||||
recipeConfig: null, // Clear recipe when resetting chat
|
||||
});
|
||||
// Clear draft when resetting chat
|
||||
clearDraft();
|
||||
};
|
||||
|
||||
const setRecipeConfig = (recipe: Recipe | null) => {
|
||||
setChat({
|
||||
...chat,
|
||||
recipeConfig: recipe,
|
||||
});
|
||||
};
|
||||
|
||||
const clearRecipeConfig = () => {
|
||||
setChat({
|
||||
...chat,
|
||||
recipeConfig: null,
|
||||
});
|
||||
};
|
||||
|
||||
const hasActiveSession = chat.messages.length > 0;
|
||||
|
||||
const value: ChatContextType = {
|
||||
chat,
|
||||
setChat,
|
||||
resetChat,
|
||||
hasActiveSession,
|
||||
setRecipeConfig,
|
||||
clearRecipeConfig,
|
||||
draft,
|
||||
setDraft,
|
||||
clearDraft,
|
||||
contextKey,
|
||||
};
|
||||
|
||||
return <ChatContext.Provider value={value}>{children}</ChatContext.Provider>;
|
||||
};
|
||||
|
||||
export const useChatContext = (): ChatContextType | null => {
|
||||
const context = useContext(ChatContext);
|
||||
return context || null;
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
import React, { createContext, useContext, useState, ReactNode } from 'react';
|
||||
|
||||
interface DraftContextType {
|
||||
getDraft: (contextKey: string) => string;
|
||||
setDraft: (contextKey: string, draft: string) => void;
|
||||
clearDraft: (contextKey: string) => void;
|
||||
}
|
||||
|
||||
const DraftContext = createContext<DraftContextType | undefined>(undefined);
|
||||
|
||||
export const DraftProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||
// Store all drafts by contextKey
|
||||
const [drafts, setDrafts] = useState<Record<string, string>>({});
|
||||
|
||||
const getDraft = (contextKey: string): string => {
|
||||
return drafts[contextKey] || '';
|
||||
};
|
||||
|
||||
const setDraft = (contextKey: string, draft: string) => {
|
||||
setDrafts((prev) => ({ ...prev, [contextKey]: draft }));
|
||||
};
|
||||
|
||||
const clearDraft = (contextKey: string) => {
|
||||
setDrafts((prev) => {
|
||||
const newDrafts = { ...prev };
|
||||
delete newDrafts[contextKey];
|
||||
return newDrafts;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<DraftContext.Provider value={{ getDraft, setDraft, clearDraft }}>
|
||||
{children}
|
||||
</DraftContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useDraftContext = (): DraftContextType => {
|
||||
const context = useContext(DraftContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useDraftContext must be used within a DraftProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
Reference in New Issue
Block a user