Commit fedb1847 authored by Administrator's avatar Administrator

Update frontend/src/store.jsx via Son of Anton

parent 848c5256
import React, { createContext, useContext, useReducer } from "react"; import React, { createContext, useContext, useReducer, useEffect } from "react";
import { setDispatch } from "./streamManager";
const AppContext = createContext(null); const AppContext = createContext(null);
...@@ -9,12 +10,11 @@ const initialState = { ...@@ -9,12 +10,11 @@ const initialState = {
activeChatId: null, activeChatId: null,
chatMessages: {}, chatMessages: {},
activeStreams: {}, activeStreams: {},
sidebarOpen: false,
}; };
function reducer(state, action) { function reducer(state, action) {
switch (action.type) { switch (action.type) {
case "LOGIN": case "SET_AUTH":
localStorage.setItem("token", action.token); localStorage.setItem("token", action.token);
return { ...state, token: action.token, user: action.user }; return { ...state, token: action.token, user: action.user };
case "LOGOUT": case "LOGOUT":
...@@ -22,35 +22,42 @@ function reducer(state, action) { ...@@ -22,35 +22,42 @@ function reducer(state, action) {
return { ...initialState, token: null }; return { ...initialState, token: null };
case "SET_USER": case "SET_USER":
return { ...state, user: action.user }; return { ...state, user: action.user };
case "SET_CHATS": case "SET_CHATS":
return { ...state, chats: action.chats }; return { ...state, chats: action.chats };
case "SET_ACTIVE_CHAT": case "SET_ACTIVE_CHAT":
return { ...state, activeChatId: action.chatId, sidebarOpen: false }; return { ...state, activeChatId: action.chatId };
case "ADD_CHAT": case "ADD_CHAT":
return { ...state, chats: [action.chat, ...state.chats], activeChatId: action.chat.id, sidebarOpen: false }; return { ...state, chats: [action.chat, ...state.chats] };
case "UPDATE_CHAT": case "UPDATE_CHAT": {
return { ...state, chats: state.chats.map(c => c.id === action.chat.id ? { ...c, ...action.chat } : c) }; const updated = state.chats.map((c) =>
case "REMOVE_CHAT": { c.id === action.chat.id ? { ...c, ...action.chat } : c
const remaining = state.chats.filter(c => c.id !== action.chatId); );
return { ...state, chats: remaining, activeChatId: state.activeChatId === action.chatId ? remaining[0]?.id || null : state.activeChatId }; return { ...state, chats: updated };
} }
case "REMOVE_CHAT":
return {
...state,
chats: state.chats.filter((c) => c.id !== action.chatId),
activeChatId: state.activeChatId === action.chatId ? null : state.activeChatId,
chatMessages: { ...state.chatMessages, [action.chatId]: undefined },
};
case "SET_MESSAGES": case "SET_MESSAGES":
return { ...state, chatMessages: { ...state.chatMessages, [action.chatId]: action.messages } }; return {
...state,
chatMessages: { ...state.chatMessages, [action.chatId]: action.messages },
};
case "ADD_MESSAGE": { case "ADD_MESSAGE": {
const prev = state.chatMessages[action.chatId] || []; const prev = state.chatMessages[action.chatId] || [];
return { ...state, chatMessages: { ...state.chatMessages, [action.chatId]: [...prev, action.message] } }; return {
...state,
chatMessages: { ...state.chatMessages, [action.chatId]: [...prev, action.message] },
};
} }
case "SET_STREAMING": case "SET_STREAMING":
return { ...state, activeStreams: action.streaming ? { ...state.activeStreams, [action.chatId]: true } : Object.fromEntries(Object.entries(state.activeStreams).filter(([k]) => k !== action.chatId)) }; return {
...state,
case "SET_SIDEBAR_OPEN": activeStreams: { ...state.activeStreams, [action.chatId]: action.streaming },
return { ...state, sidebarOpen: action.open }; };
case "TOGGLE_SIDEBAR":
return { ...state, sidebarOpen: !state.sidebarOpen };
default: default:
return state; return state;
} }
...@@ -58,25 +65,20 @@ function reducer(state, action) { ...@@ -58,25 +65,20 @@ function reducer(state, action) {
export function AppProvider({ children }) { export function AppProvider({ children }) {
const [state, dispatch] = useReducer(reducer, initialState); const [state, dispatch] = useReducer(reducer, initialState);
return <AppContext.Provider value={{ state, dispatch }}>{children}</AppContext.Provider>;
useEffect(() => {
setDispatch(dispatch);
}, [dispatch]);
return (
<AppContext.Provider value={{ state, dispatch }}>
{children}
</AppContext.Provider>
);
} }
export function useApp() { export function useApp() {
const ctx = useContext(AppContext); const ctx = useContext(AppContext);
if (!ctx) throw new Error("useApp must be inside AppProvider"); if (!ctx) throw new Error("useApp must be used within AppProvider");
return ctx; return ctx;
}
/** Helper to get current user permissions with sane defaults */
export function usePermissions() {
const { state } = useApp();
const p = state.user?.permissions;
if (!p) return {
can_use_web_search: false, can_use_ui_design: false, can_use_knowledge_base: true,
can_use_gitlab: false, can_use_attachments: true, can_export_pptx: true, can_export_docx: true,
allowed_models: "all", max_tokens_cap: 4096, max_reasoning_budget: 0, max_chats: 50,
max_messages_per_day: 100, max_knowledge_bases: 3, max_documents_per_kb: 20,
max_attachment_size_mb: 10, max_attachments_per_message: 5,
};
return p;
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment