fix(communications): make email optional and align switches
This commit is contained in:
parent
ac2db590d0
commit
999c1a0c1e
4 changed files with 41 additions and 16 deletions
|
|
@ -24,8 +24,15 @@ export function CommunicationsModule() {
|
||||||
const [isAddContactOpen, setIsAddContactOpen] = useState(false);
|
const [isAddContactOpen, setIsAddContactOpen] = useState(false);
|
||||||
const [isConnectChannelOpen, setIsConnectChannelOpen] = useState(false);
|
const [isConnectChannelOpen, setIsConnectChannelOpen] = useState(false);
|
||||||
const [connectMode, setConnectMode] = useState<'messenger' | 'email'>('messenger');
|
const [connectMode, setConnectMode] = useState<'messenger' | 'email'>('messenger');
|
||||||
|
const [showEmailTab, setShowEmailTab] = useState(() => localStorage.getItem('krona-show-email') === 'true');
|
||||||
const [showChannelsTab, setShowChannelsTab] = useState(() => localStorage.getItem('krona-show-bot-channels') === 'true');
|
const [showChannelsTab, setShowChannelsTab] = useState(() => localStorage.getItem('krona-show-bot-channels') === 'true');
|
||||||
|
|
||||||
|
const updateEmailVisibility = (enabled: boolean) => {
|
||||||
|
setShowEmailTab(enabled);
|
||||||
|
localStorage.setItem('krona-show-email', String(enabled));
|
||||||
|
if (!enabled && currentTab === 'email') handleTabChange('settings');
|
||||||
|
};
|
||||||
|
|
||||||
const updateChannelsVisibility = (enabled: boolean) => {
|
const updateChannelsVisibility = (enabled: boolean) => {
|
||||||
setShowChannelsTab(enabled);
|
setShowChannelsTab(enabled);
|
||||||
localStorage.setItem('krona-show-bot-channels', String(enabled));
|
localStorage.setItem('krona-show-bot-channels', String(enabled));
|
||||||
|
|
@ -34,9 +41,12 @@ export function CommunicationsModule() {
|
||||||
|
|
||||||
// Sync tab with URL search param
|
// Sync tab with URL search param
|
||||||
const urlTab = searchParams.get('tab') as CommunicationTab | null;
|
const urlTab = searchParams.get('tab') as CommunicationTab | null;
|
||||||
const currentTab = urlTab && ['messengers', 'email', 'channels', 'contacts', 'settings'].includes(urlTab)
|
const requestedTab = urlTab && ['messengers', 'email', 'channels', 'contacts', 'settings'].includes(urlTab) ? urlTab : activeTab;
|
||||||
? urlTab
|
const currentTab = requestedTab === 'email' && !showEmailTab
|
||||||
: activeTab;
|
? 'messengers'
|
||||||
|
: requestedTab === 'channels' && !showChannelsTab
|
||||||
|
? 'messengers'
|
||||||
|
: requestedTab;
|
||||||
|
|
||||||
const handleTabChange = (tab: CommunicationTab) => {
|
const handleTabChange = (tab: CommunicationTab) => {
|
||||||
setActiveTab(tab);
|
setActiveTab(tab);
|
||||||
|
|
@ -53,6 +63,7 @@ export function CommunicationsModule() {
|
||||||
unreadChats={48}
|
unreadChats={48}
|
||||||
unreadEmails={10}
|
unreadEmails={10}
|
||||||
unreadChannels={4}
|
unreadChannels={4}
|
||||||
|
showEmailTab={showEmailTab}
|
||||||
showChannelsTab={showChannelsTab}
|
showChannelsTab={showChannelsTab}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -74,7 +85,7 @@ export function CommunicationsModule() {
|
||||||
{currentTab === 'contacts' && (
|
{currentTab === 'contacts' && (
|
||||||
<ContactsView onAddContactModal={() => setIsAddContactOpen(true)} />
|
<ContactsView onAddContactModal={() => setIsAddContactOpen(true)} />
|
||||||
)}
|
)}
|
||||||
{currentTab === 'settings' && <SettingsView showChannelsTab={showChannelsTab} onShowChannelsTabChange={updateChannelsVisibility} />}
|
{currentTab === 'settings' && <SettingsView showEmailTab={showEmailTab} onShowEmailTabChange={updateEmailVisibility} showChannelsTab={showChannelsTab} onShowChannelsTabChange={updateChannelsVisibility} />}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{/* Modals */}
|
{/* Modals */}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ interface CommunicationsHeaderProps {
|
||||||
unreadChats: number;
|
unreadChats: number;
|
||||||
unreadEmails: number;
|
unreadEmails: number;
|
||||||
unreadChannels: number;
|
unreadChannels: number;
|
||||||
|
showEmailTab: boolean;
|
||||||
showChannelsTab: boolean;
|
showChannelsTab: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -18,6 +19,7 @@ export function CommunicationsHeader({
|
||||||
unreadChats,
|
unreadChats,
|
||||||
unreadEmails,
|
unreadEmails,
|
||||||
unreadChannels,
|
unreadChannels,
|
||||||
|
showEmailTab,
|
||||||
showChannelsTab,
|
showChannelsTab,
|
||||||
}: CommunicationsHeaderProps) {
|
}: CommunicationsHeaderProps) {
|
||||||
const tabItems = [
|
const tabItems = [
|
||||||
|
|
@ -49,7 +51,11 @@ export function CommunicationsHeader({
|
||||||
label: 'Настройки',
|
label: 'Настройки',
|
||||||
icon: <Settings className="w-4 h-4" />,
|
icon: <Settings className="w-4 h-4" />,
|
||||||
},
|
},
|
||||||
].filter((item) => item.id !== 'channels' || showChannelsTab);
|
].filter((item) => {
|
||||||
|
if (item.id === 'email') return showEmailTab;
|
||||||
|
if (item.id === 'channels') return showChannelsTab;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="bg-[var(--krona-surface)] border-b border-[var(--krona-border-subtle)] px-3 sm:px-5 py-1.5 shrink-0 overflow-hidden">
|
<header className="bg-[var(--krona-surface)] border-b border-[var(--krona-border-subtle)] px-3 sm:px-5 py-1.5 shrink-0 overflow-hidden">
|
||||||
|
|
|
||||||
|
|
@ -684,13 +684,6 @@ export function MessengersView({ onOpenConnectModal, onOpenAddContactModal }: Me
|
||||||
>
|
>
|
||||||
MAX
|
MAX
|
||||||
</ConnectorPill>
|
</ConnectorPill>
|
||||||
<ConnectorPill
|
|
||||||
active={activeConnector === 'email'}
|
|
||||||
onClick={() => setActiveConnector('email')}
|
|
||||||
count={10}
|
|
||||||
>
|
|
||||||
Email
|
|
||||||
</ConnectorPill>
|
|
||||||
</div>
|
</div>
|
||||||
{/* Smooth fade-out indicator on the right edge */}
|
{/* Smooth fade-out indicator on the right edge */}
|
||||||
<div className="pointer-events-none absolute right-0 top-0 bottom-0 w-8 bg-gradient-to-l from-[var(--krona-surface)] to-transparent" />
|
<div className="pointer-events-none absolute right-0 top-0 bottom-0 w-8 bg-gradient-to-l from-[var(--krona-surface)] to-transparent" />
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,13 @@ import { Button, Badge } from '@krona/ui';
|
||||||
import { useToast } from '../../../shared/ui';
|
import { useToast } from '../../../shared/ui';
|
||||||
|
|
||||||
interface SettingsViewProps {
|
interface SettingsViewProps {
|
||||||
|
showEmailTab: boolean;
|
||||||
|
onShowEmailTabChange: (enabled: boolean) => void;
|
||||||
showChannelsTab: boolean;
|
showChannelsTab: boolean;
|
||||||
onShowChannelsTabChange: (enabled: boolean) => void;
|
onShowChannelsTabChange: (enabled: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SettingsView({ showChannelsTab, onShowChannelsTabChange }: SettingsViewProps) {
|
export function SettingsView({ showEmailTab, onShowEmailTabChange, showChannelsTab, onShowChannelsTabChange }: SettingsViewProps) {
|
||||||
const { showToast } = useToast();
|
const { showToast } = useToast();
|
||||||
const {
|
const {
|
||||||
integrations,
|
integrations,
|
||||||
|
|
@ -50,9 +52,21 @@ export function SettingsView({ showChannelsTab, onShowChannelsTabChange }: Setti
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 min-h-0 flex flex-col p-4 sm:p-6 bg-[var(--krona-bg-workspace)] overflow-y-auto space-y-6">
|
<div className="flex-1 min-h-0 flex flex-col p-4 sm:p-6 bg-[var(--krona-bg-workspace)] overflow-y-auto space-y-6">
|
||||||
<section className="p-4 sm:p-5 rounded-2xl bg-[var(--krona-surface)] border border-[var(--krona-border-subtle)] shadow-xs">
|
<section className="p-4 sm:p-5 rounded-2xl bg-[var(--krona-surface)] border border-[var(--krona-border-subtle)] shadow-xs">
|
||||||
<div className="flex items-center justify-between gap-4">
|
<h3 className="font-bold text-base text-[var(--krona-text-primary)]">Отображение разделов</h3>
|
||||||
|
<p className="text-xs text-[var(--krona-text-secondary)] mt-0.5 mb-4">Показывайте только те способы связи, которыми пользуется организация</p>
|
||||||
|
<div className="divide-y divide-[var(--krona-border-subtle)]">
|
||||||
|
<div className="flex items-center justify-between gap-4 py-3">
|
||||||
|
<div>
|
||||||
|
<div className="font-semibold text-sm text-[var(--krona-text-primary)]">Email</div>
|
||||||
|
<div className="text-xs text-[var(--krona-text-secondary)]">Почтовые ящики и переписка</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" role="switch" aria-checked={showEmailTab} onClick={() => onShowEmailTabChange(!showEmailTab)} className={`relative w-12 h-7 rounded-full transition-colors shrink-0 ${showEmailTab ? 'bg-[var(--krona-primary)]' : 'bg-[var(--krona-surface-muted)]'}`} aria-label="Показывать раздел Email">
|
||||||
|
<span className={`absolute left-1 top-1 w-5 h-5 rounded-full bg-white shadow-sm transition-transform ${showEmailTab ? 'translate-x-5' : 'translate-x-0'}`} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-between gap-4 py-3">
|
||||||
<div>
|
<div>
|
||||||
<h3 className="font-bold text-base text-[var(--krona-text-primary)]">Раздел «Каналы»</h3>
|
<div className="font-semibold text-sm text-[var(--krona-text-primary)]">Каналы</div>
|
||||||
<p className="text-xs text-[var(--krona-text-secondary)] mt-0.5">Боты и публичные каналы организации</p>
|
<p className="text-xs text-[var(--krona-text-secondary)] mt-0.5">Боты и публичные каналы организации</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
|
@ -63,8 +77,9 @@ export function SettingsView({ showChannelsTab, onShowChannelsTabChange }: Setti
|
||||||
className={`relative w-12 h-7 rounded-full transition-colors shrink-0 ${showChannelsTab ? 'bg-[var(--krona-primary)]' : 'bg-[var(--krona-surface-muted)]'}`}
|
className={`relative w-12 h-7 rounded-full transition-colors shrink-0 ${showChannelsTab ? 'bg-[var(--krona-primary)]' : 'bg-[var(--krona-surface-muted)]'}`}
|
||||||
aria-label="Показывать раздел Каналы"
|
aria-label="Показывать раздел Каналы"
|
||||||
>
|
>
|
||||||
<span className={`absolute top-1 w-5 h-5 rounded-full bg-white shadow transition-transform ${showChannelsTab ? 'translate-x-6' : 'translate-x-1'}`} />
|
<span className={`absolute left-1 top-1 w-5 h-5 rounded-full bg-white shadow-sm transition-transform ${showChannelsTab ? 'translate-x-5' : 'translate-x-0'}`} />
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{/* 1. Connected Messengers & Connectors */}
|
{/* 1. Connected Messengers & Connectors */}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue