feat(app): fix sizes & placement for smaller screens

This commit is contained in:
ItzCrazyKns
2025-10-21 12:23:18 +05:30
parent ff37225253
commit 7fb7fb9692
5 changed files with 98 additions and 45 deletions

View File

@@ -78,7 +78,7 @@ const ModelProvider = ({
)}
onClick={() => setOpen(!open)}
>
<p className="text-black dark:text-white font-medium">
<p className="text-sm lg:text-base text-black dark:text-white font-medium">
{modelProvider.name}
</p>
<div className="flex items-center gap-4">
@@ -115,7 +115,7 @@ const ModelProvider = ({
{modelProvider.chatModels.length > 0 && (
<div className="flex flex-col gap-y-2">
<div className="flex flex-row w-full justify-between items-center">
<p className="text-xs text-black/70 dark:text-white/70">
<p className="text-[11px] lg:text-xs text-black/70 dark:text-white/70">
Chat models
</p>
<AddModel
@@ -126,7 +126,7 @@ const ModelProvider = ({
</div>
<div className="flex flex-col gap-2">
{modelProvider.chatModels.some((m) => m.key === 'error') ? (
<div className="flex flex-row items-center gap-2 text-sm text-red-500 dark:text-red-400 rounded-lg bg-red-50 dark:bg-red-950/20 px-3 py-2 border border-red-200 dark:border-red-900/30">
<div className="flex flex-row items-center gap-2 text-xs lg:text-sm text-red-500 dark:text-red-400 rounded-lg bg-red-50 dark:bg-red-950/20 px-3 py-2 border border-red-200 dark:border-red-900/30">
<AlertCircle size={16} className="shrink-0" />
<span className="break-words">
{
@@ -141,7 +141,7 @@ const ModelProvider = ({
{modelProvider.chatModels.map((model, index) => (
<div
key={`${modelProvider.id}-chat-${model.key}-${index}`}
className="flex flex-row items-center space-x-1 text-sm text-black/70 dark:text-white/70 rounded-lg bg-light-secondary dark:bg-dark-secondary px-3 py-1.5"
className="flex flex-row items-center space-x-1 text-xs lg:text-sm text-black/70 dark:text-white/70 rounded-lg bg-light-secondary dark:bg-dark-secondary px-3 py-1.5"
>
<span>{model.name}</span>
<button
@@ -161,7 +161,7 @@ const ModelProvider = ({
{modelProvider.embeddingModels.length > 0 && (
<div className="flex flex-col gap-y-2">
<div className="flex flex-row w-full justify-between items-center">
<p className="text-xs text-black/70 dark:text-white/70">
<p className="text-[11px] lg:text-xs text-black/70 dark:text-white/70">
Embedding models
</p>
<AddModel
@@ -174,7 +174,7 @@ const ModelProvider = ({
{modelProvider.embeddingModels.some(
(m) => m.key === 'error',
) ? (
<div className="flex flex-row items-center gap-2 text-sm text-red-500 dark:text-red-400 rounded-lg bg-red-50 dark:bg-red-950/20 px-3 py-2 border border-red-200 dark:border-red-900/30">
<div className="flex flex-row items-center gap-2 text-xs lg:text-sm text-red-500 dark:text-red-400 rounded-lg bg-red-50 dark:bg-red-950/20 px-3 py-2 border border-red-200 dark:border-red-900/30">
<AlertCircle size={16} className="shrink-0" />
<span className="break-words">
{
@@ -189,7 +189,7 @@ const ModelProvider = ({
{modelProvider.embeddingModels.map((model, index) => (
<div
key={`${modelProvider.id}-embedding-${model.key}-${index}`}
className="flex flex-row items-center space-x-1 text-sm text-black/70 dark:text-white/70 rounded-lg bg-light-secondary dark:bg-dark-secondary px-3 py-1.5"
className="flex flex-row items-center space-x-1 text-xs lg:text-sm text-black/70 dark:text-white/70 rounded-lg bg-light-secondary dark:bg-dark-secondary px-3 py-1.5"
>
<span>{model.name}</span>
<button

View File

@@ -18,16 +18,23 @@ const ModelSelect = ({
const handleSave = async (newValue: string) => {
setLoading(true);
setSelectedModel(newValue);
console.log(newValue);
try {
if (type === 'chat') {
localStorage.setItem('chatModelProviderId', newValue.split('/')[0]);
localStorage.setItem('chatModelKey', newValue.split('/')[1]);
localStorage.setItem(
'chatModelKey',
newValue.split('/').slice(1).join('/'),
);
} else {
localStorage.setItem(
'embeddingModelProviderId',
newValue.split('/')[0],
);
localStorage.setItem('embeddingModelKey', newValue.split('/')[1]);
localStorage.setItem(
'embeddingModelKey',
newValue.split('/').slice(1).join('/'),
);
}
} catch (error) {
console.error('Error saving config:', error);
@@ -38,13 +45,13 @@ const ModelSelect = ({
};
return (
<section className="rounded-xl border border-light-200 bg-light-primary/80 p-6 transition-colors dark:border-dark-200 dark:bg-dark-primary/80">
<div className="space-y-5">
<section className="rounded-xl border border-light-200 bg-light-primary/80 p-4 lg:p-6 transition-colors dark:border-dark-200 dark:bg-dark-primary/80">
<div className="space-y-3 lg:space-y-5">
<div>
<h4 className="text-base text-black dark:text-white">
<h4 className="text-sm lg:text-base text-black dark:text-white">
Select {type === 'chat' ? 'Chat Model' : 'Embedding Model'}
</h4>
<p className="text-xs text-black/50 dark:text-white/50">
<p className="text-[11px] lg:text-xs text-black/50 dark:text-white/50">
{type === 'chat'
? 'Select the model to use for chat responses'
: 'Select the model to use for embeddings'}
@@ -68,7 +75,7 @@ const ModelSelect = ({
})),
)
}
className="w-full rounded-lg border border-light-200 dark:border-dark-200 bg-light-primary dark:bg-dark-primary px-4 py-3 text-sm text-black/80 dark:text-white/80 placeholder:text-black/40 dark:placeholder:text-white/40 focus-visible:outline-none focus-visible:border-light-300 dark:focus-visible:border-dark-300 transition-colors disabled:cursor-not-allowed disabled:opacity-60 cursor-pointer capitalize pr-12"
className="!text-xs lg:!text-sm"
loading={loading}
disabled={loading}
/>

View File

@@ -1,5 +1,11 @@
import { Dialog, DialogPanel } from '@headlessui/react';
import { BrainCog, ChevronLeft, Search, Settings } from 'lucide-react';
import {
ArrowLeft,
BrainCog,
ChevronLeft,
Search,
Settings,
} from 'lucide-react';
import General from './Sections/General';
import { motion } from 'framer-motion';
import { useEffect, useState } from 'react';
@@ -8,9 +14,11 @@ import Loader from '../ui/Loader';
import { cn } from '@/lib/utils';
import Models from './Sections/Models/Section';
import SearchSection from './Sections/Search';
import Select from '@/components/ui/Select';
const sections = [
{
key: 'general',
name: 'General',
description: 'Adjust common settings.',
icon: Settings,
@@ -18,6 +26,7 @@ const sections = [
dataAdd: 'general',
},
{
key: 'models',
name: 'Models',
description: 'Configure model settings.',
icon: BrainCog,
@@ -25,6 +34,7 @@ const sections = [
dataAdd: 'modelProviders',
},
{
key: 'search',
name: 'Search',
description: 'Manage search settings.',
icon: Search,
@@ -42,7 +52,12 @@ const SettingsDialogue = ({
}) => {
const [isLoading, setIsLoading] = useState(true);
const [config, setConfig] = useState<any>(null);
const [activeSection, setActiveSection] = useState(sections[0]);
const [activeSection, setActiveSection] = useState<string>(sections[0].key);
const [selectedSection, setSelectedSection] = useState(sections[0]);
useEffect(() => {
setSelectedSection(sections.find((s) => s.key === activeSection)!);
}, [activeSection]);
useEffect(() => {
if (isOpen) {
@@ -83,14 +98,14 @@ const SettingsDialogue = ({
transition={{ duration: 0.1 }}
className="fixed inset-0 flex w-screen items-center justify-center p-4 bg-black/30 backdrop-blur-sm h-screen"
>
<DialogPanel className="space-y-4 border border-light-200 dark:border-dark-200 bg-light-primary dark:bg-dark-primary backdrop-blur-lg rounded-xl h-[calc(100vh-2%)] w-[calc(100vw-2%)] md:h-[calc(100vh-7%)] md:w-[calc(100vw-7%)] lg:h-[calc(100vh-20%)] lg:w-[calc(100vw-30%)]">
<DialogPanel className="space-y-4 border border-light-200 dark:border-dark-200 bg-light-primary dark:bg-dark-primary backdrop-blur-lg rounded-xl h-[calc(100vh-2%)] w-[calc(100vw-2%)] md:h-[calc(100vh-7%)] md:w-[calc(100vw-7%)] lg:h-[calc(100vh-20%)] lg:w-[calc(100vw-30%)] overflow-hidden flex flex-col">
{isLoading ? (
<div className="flex items-center justify-center h-full w-full">
<Loader />
</div>
) : (
<div className="flex flex-1 inset-0 h-full">
<div className="w-[240px] border-r border-white-200 dark:border-dark-200 h-full px-3 pt-3 flex flex-col">
<div className="flex flex-1 inset-0 h-full overflow-hidden">
<div className="hidden lg:flex flex-col w-[240px] border-r border-white-200 dark:border-dark-200 h-full px-3 pt-3 overflow-y-auto">
<button
onClick={() => setIsOpen(false)}
className="group flex flex-row items-center hover:bg-light-200 hover:dark:bg-dark-200 p-2 rounded-lg"
@@ -109,11 +124,11 @@ const SettingsDialogue = ({
key={section.dataAdd}
className={cn(
`flex flex-row items-center space-x-2 px-2 py-1.5 rounded-lg w-full text-sm hover:bg-light-200 hover:dark:bg-dark-200 transition duration-200 active:scale-95`,
activeSection.name === section.name
activeSection === section.key
? 'bg-light-200 dark:bg-dark-200 text-black/90 dark:text-white/90'
: ' text-black/70 dark:text-white/70',
)}
onClick={() => setActiveSection(section)}
onClick={() => setActiveSection(section.key)}
>
<section.icon size={17} />
<p>{section.name}</p>
@@ -121,23 +136,50 @@ const SettingsDialogue = ({
))}
</div>
</div>
<div className="w-full">
{activeSection.component && (
<div className="flex h-full flex-col">
<div className="border-b border-light-200/60 px-6 pb-6 pt-8 dark:border-dark-200/60">
<div className="w-full flex flex-col overflow-hidden">
<div className="flex flex-row lg:hidden w-full justify-between px-[20px] my-4 flex-shrink-0">
<button
onClick={() => setIsOpen(false)}
className="group flex flex-row items-center hover:bg-light-200 hover:dark:bg-dark-200 rounded-lg mr-[40%]"
>
<ArrowLeft
size={18}
className="text-black/50 dark:text-white/50 group-hover:text-black/70 group-hover:dark:text-white/70"
/>
</button>
<Select
options={sections.map((section) => {
return {
value: section.key,
key: section.key,
label: section.name,
};
})}
value={activeSection}
onChange={(e) => {
setActiveSection(e.target.value);
}}
className="!text-xs lg:!text-sm"
/>
</div>
{selectedSection.component && (
<div className="flex flex-1 flex-col overflow-hidden">
<div className="border-b border-light-200/60 px-6 pb-6 lg:pt-6 dark:border-dark-200/60 flex-shrink-0">
<div className="flex flex-col">
<h4 className="font-medium text-black dark:text-white">
{activeSection.name}
<h4 className="font-medium text-black dark:text-white text-sm lg:text-base">
{selectedSection.name}
</h4>
<p className="text-xs text-black/50 dark:text-white/50">
{activeSection.description}
<p className="text-[11px] lg:text-xs text-black/50 dark:text-white/50">
{selectedSection.description}
</p>
</div>
</div>
<activeSection.component
fields={config.fields[activeSection.dataAdd]}
values={config.values[activeSection.dataAdd]}
/>
<div className="flex-1 overflow-y-auto">
<selectedSection.component
fields={config.fields[selectedSection.dataAdd]}
values={config.values[selectedSection.dataAdd]}
/>
</div>
</div>
)}
</div>

View File

@@ -59,11 +59,13 @@ const SettingsSelect = ({
};
return (
<section className="rounded-xl border border-light-200 bg-light-primary/80 p-6 transition-colors dark:border-dark-200 dark:bg-dark-primary/80">
<div className="space-y-5">
<section className="rounded-xl border border-light-200 bg-light-primary/80 p-4 lg:p-6 transition-colors dark:border-dark-200 dark:bg-dark-primary/80">
<div className="space-y-3 lg:space-y-5">
<div>
<h4 className="text-base text-black dark:text-white">{field.name}</h4>
<p className="text-xs text-black/50 dark:text-white/50">
<h4 className="text-sm lg:text-base text-black dark:text-white">
{field.name}
</h4>
<p className="text-[11px] lg:text-xs text-black/50 dark:text-white/50">
{field.description}
</p>
</div>
@@ -74,7 +76,7 @@ const SettingsSelect = ({
value: option.value,
label: option.name,
}))}
className="w-full rounded-lg border border-light-200 dark:border-dark-200 bg-light-primary dark:bg-dark-primary px-4 py-3 text-sm text-black/80 dark:text-white/80 placeholder:text-black/40 dark:placeholder:text-white/40 focus-visible:outline-none focus-visible:border-light-300 dark:focus-visible:border-dark-300 transition-colors disabled:cursor-not-allowed disabled:opacity-60 cursor-pointer capitalize pr-12"
className="!text-xs lg:!text-sm"
loading={loading}
disabled={loading}
/>
@@ -128,11 +130,13 @@ const SettingsInput = ({
};
return (
<section className="rounded-xl border border-light-200 bg-light-primary/80 p-6 transition-colors dark:border-dark-200 dark:bg-dark-primary/80">
<div className="space-y-5">
<section className="rounded-xl border border-light-200 bg-light-primary/80 p-4 lg:p-6 transition-colors dark:border-dark-200 dark:bg-dark-primary/80">
<div className="space-y-3 lg:space-y-5">
<div>
<h4 className="text-base text-black dark:text-white">{field.name}</h4>
<p className="text-xs text-black/50 dark:text-white/50">
<h4 className="text-sm lg:text-base text-black dark:text-white">
{field.name}
</h4>
<p className="text-[11px] lg:text-xs text-black/50 dark:text-white/50">
{field.description}
</p>
</div>
@@ -141,7 +145,7 @@ const SettingsInput = ({
value={value ?? field.default ?? ''}
onChange={(event) => setValue(event.target.value)}
onBlur={(event) => handleSave(event.target.value)}
className="w-full rounded-lg border border-light-200 dark:border-dark-200 bg-light-primary dark:bg-dark-primary px-4 py-3 pr-10 text-sm text-black/80 dark:text-white/80 placeholder:text-black/40 dark:placeholder:text-white/40 focus-visible:outline-none focus-visible:border-light-300 dark:focus-visible:border-dark-300 transition-colors disabled:cursor-not-allowed disabled:opacity-60"
className="w-full rounded-lg border border-light-200 dark:border-dark-200 bg-light-primary dark:bg-dark-primary px-3 py-2 lg:px-4 lg:py-3 pr-10 !text-xs lg:!text-sm text-black/80 dark:text-white/80 placeholder:text-black/40 dark:placeholder:text-white/40 focus-visible:outline-none focus-visible:border-light-300 dark:focus-visible:border-dark-300 transition-colors disabled:cursor-not-allowed disabled:opacity-60"
placeholder={field.placeholder}
type="text"
disabled={loading}

View File

@@ -3,7 +3,7 @@ import { Loader2, ChevronDown } from 'lucide-react';
import { SelectHTMLAttributes, forwardRef } from 'react';
interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
options: { value: string; label: string; disabled?: boolean }[];
options: { value: any; label: string; disabled?: boolean }[];
loading?: boolean;
}
@@ -21,7 +21,7 @@ export const Select = forwardRef<HTMLSelectElement, SelectProps>(
ref={ref}
disabled={disabled || loading}
className={cn(
'bg-light-secondary dark:bg-dark-secondary px-3 py-2 flex items-center overflow-hidden border border-light-200 dark:border-dark-200 dark:text-white rounded-lg text-sm appearance-none w-full pr-10',
'bg-light-secondary dark:bg-dark-secondary px-3 py-2 flex items-center overflow-hidden border border-light-200 dark:border-dark-200 dark:text-white rounded-lg appearance-none w-full pr-10 text-xs lg:text-sm',
className,
)}
>