update contacts screen
This commit is contained in:
+98
-67
@@ -5,40 +5,44 @@ import { IOSDevice } from './frames/IOSDevice.jsx';
|
||||
import { FitWrap } from './FitWrap.jsx';
|
||||
import { ClinicLeafletMap } from './ClinicLeafletMap.jsx';
|
||||
|
||||
/** Палитра и типографика ближе к скриншоту Oclinica */
|
||||
/** Палитра и toolbar синхронизированы с clinic-ecosystem mobile-app */
|
||||
const oc = {
|
||||
pageBg: '#F2F2F2',
|
||||
pageBg: '#FFFFFF',
|
||||
headerBg: '#FFFFFF',
|
||||
card: '#FFFFFF',
|
||||
/** Телефон и «Записаться на приём» — один фон и цвет текста */
|
||||
phoneBtnBg: '#9ad1d8',
|
||||
phoneBtnFg: '#001c22',
|
||||
phoneBtnShadow: '0 3px 14px rgba(0, 28, 34, 0.08)',
|
||||
bookBtnBg: '#9ad1d8',
|
||||
bookBtnFg: '#001c22',
|
||||
chatBorder: '#C4A574',
|
||||
chatFg: '#6B542E',
|
||||
openBadgeBg: '#769197',
|
||||
border: '#E3EBEB',
|
||||
fg: '#172121',
|
||||
mutedFg: '#6F7D7D',
|
||||
primary: '#4c9a9a',
|
||||
/** Телефон и «Записаться на приём» как primary из mobile-app */
|
||||
phoneBtnBg: '#4c9a9a',
|
||||
phoneBtnFg: '#FFFFFF',
|
||||
phoneBtnShadow: '0 4px 14px rgba(76, 154, 154, 0.24)',
|
||||
bookBtnBg: '#4c9a9a',
|
||||
bookBtnFg: '#FFFFFF',
|
||||
chatBorder: '#D8E3E3',
|
||||
chatFg: '#4A5A5A',
|
||||
openBadgeBg: '#4c9a9a',
|
||||
openBadgeFg: '#FFFFFF',
|
||||
/** Блок «Почему нас выбирают» */
|
||||
hWhy: '#B88E71',
|
||||
whyWrapBg: '#EBEDF0',
|
||||
hWhy: '#4A6E6E',
|
||||
whyWrapBg: '#F4F8F8',
|
||||
/** Звезда над заголовком «Почему нас выбирают» */
|
||||
whyHeaderStar: '#5f96a0',
|
||||
whyHeaderStar: '#4c9a9a',
|
||||
/** Иконки Email / Веб-сайт */
|
||||
whyInfoIconBg: '#f8faf9',
|
||||
whyInfoIconFg: '#619799',
|
||||
whyRowLabel: '#5A9E95',
|
||||
whyRowValue: '#3A4149',
|
||||
statCardValue: '#599195',
|
||||
statCardLabel: '#6B7684',
|
||||
noteBg: '#E8F4FC',
|
||||
noteBorder: '#B9D8EE',
|
||||
noteFg: '#245A7A',
|
||||
routeBtnBg: '#EBEDEF',
|
||||
routeBtnFg: '#4A5560',
|
||||
teal: '#1F8F85',
|
||||
tealDark: '#166B63',
|
||||
whyInfoIconBg: '#F7FAFA',
|
||||
whyInfoIconFg: '#4c9a9a',
|
||||
whyRowLabel: '#4c9a9a',
|
||||
whyRowValue: '#2F3B3B',
|
||||
statCardValue: '#4c9a9a',
|
||||
statCardLabel: '#6B7A7A',
|
||||
noteBg: '#ECF6F6',
|
||||
noteBorder: '#CFE3E3',
|
||||
noteFg: '#2C5F62',
|
||||
routeBtnBg: '#EEF3F3',
|
||||
routeBtnFg: '#4A5A5A',
|
||||
teal: '#4c9a9a',
|
||||
tealDark: '#4c9a9a',
|
||||
};
|
||||
|
||||
function MiniBuilding() {
|
||||
@@ -106,28 +110,57 @@ function SocialYoutubeIcon({ size = 26, color = oc.whyHeaderStar, playColor = '#
|
||||
);
|
||||
}
|
||||
|
||||
function RoundChatTabIcon({ size = 24, sw = 1.9, style }) {
|
||||
return (
|
||||
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" style={style}>
|
||||
<circle cx="12" cy="11.5" r="7.5" />
|
||||
<path d="M8.8 18.1l-2.1 2.4.5-3.4" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function OclinicaTabBar() {
|
||||
const tab = (label, Icon, active) => (
|
||||
<div
|
||||
const items = [
|
||||
{ label: 'Главная', Icon: I.home, to: '/' },
|
||||
{ label: 'Приемы', Icon: I.calendar, to: '/appointments' },
|
||||
{ label: 'Чат', Icon: RoundChatTabIcon, to: '/chat' },
|
||||
{ label: 'Профиль', Icon: I.profile, to: '/profile' },
|
||||
];
|
||||
|
||||
const tab = ({ label, Icon, to }) => (
|
||||
<Link
|
||||
key={label}
|
||||
to={to}
|
||||
style={{
|
||||
flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3,
|
||||
padding: '5px 0 2px', color: active ? oc.tealDark : '#9AA7B4',
|
||||
fontSize: 10, fontWeight: active ? 700 : 600,
|
||||
flex: 1,
|
||||
textDecoration: 'none',
|
||||
color: 'inherit',
|
||||
}}
|
||||
>
|
||||
<Icon size={22} sw={active ? 2.1 : 1.75} style={{ color: active ? oc.tealDark : '#9AA7B4' }} />
|
||||
<span>{label}</span>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
gap: 1,
|
||||
minHeight: 56,
|
||||
color: oc.mutedFg,
|
||||
fontSize: 12,
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
<Icon size={24} sw={1.9} style={{ color: oc.mutedFg }} />
|
||||
<span>{label}</span>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', paddingBottom: 20 }}>
|
||||
<Link to="/" style={{ flex: 1, textDecoration: 'none', color: 'inherit' }}>
|
||||
{tab('Главная', I.home, false)}
|
||||
</Link>
|
||||
{tab('Клиники', I.pin, true)}
|
||||
{tab('Запись', I.calendar, false)}
|
||||
{tab('Профиль', I.profile, false)}
|
||||
<div style={{ display: 'flex', gap: 8, padding: '8px 16px calc(12px + env(safe-area-inset-bottom, 0px))' }}>
|
||||
{items.map(tab)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -285,7 +318,7 @@ function ClinicCirclePhoto({ imageUrl, href }) {
|
||||
return img;
|
||||
}
|
||||
|
||||
const FOOTER_H = 162;
|
||||
const FOOTER_H = 92;
|
||||
/** Выше внутренних слоёв Leaflet (~400–700), чтобы хром не перекрывался картой при скролле */
|
||||
const Z_SCROLL = 0;
|
||||
const Z_HEADER = 2000;
|
||||
@@ -327,7 +360,7 @@ function ContactsPhoneBody() {
|
||||
background: oc.pageBg,
|
||||
overflow: 'hidden',
|
||||
fontFamily: 'var(--font-base), "Inter", system-ui, sans-serif',
|
||||
color: '#1F2A37',
|
||||
color: oc.fg,
|
||||
}}>
|
||||
<div style={{
|
||||
position: 'absolute', inset: 0,
|
||||
@@ -344,16 +377,16 @@ function ContactsPhoneBody() {
|
||||
padding: '10px 12px 11px',
|
||||
position: 'sticky', top: 0, zIndex: Z_HEADER,
|
||||
background: oc.headerBg,
|
||||
borderBottom: '1px solid #EFEFEF',
|
||||
borderBottom: `1px solid ${oc.border}`,
|
||||
}}>
|
||||
<button type="button" onClick={goBack} className="press" style={{
|
||||
width: 38, height: 38, borderRadius: 999, background: '#F5F5F5',
|
||||
width: 38, height: 38, borderRadius: 999, background: '#F4F7F7',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
border: 0,
|
||||
border: `1px solid ${oc.border}`,
|
||||
}}>
|
||||
<I.chevL size={20} style={{ color: '#2A3540' }} />
|
||||
<I.chevL size={20} style={{ color: oc.fg }} />
|
||||
</button>
|
||||
<h1 style={{ margin: 0, fontSize: 17, fontWeight: 700, textAlign: 'center', color: '#1F2A37' }}>Контакты</h1>
|
||||
<h1 style={{ margin: 0, fontSize: 17, fontWeight: 600, textAlign: 'center', color: oc.fg }}>Контакты</h1>
|
||||
<span />
|
||||
</header>
|
||||
|
||||
@@ -531,31 +564,29 @@ function ContactsPhoneBody() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ marginTop: 10 }}>
|
||||
<Link to="/" className="press" style={{
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
|
||||
width: '100%', padding: '15px 16px', borderRadius: 16, textDecoration: 'none',
|
||||
background: oc.bookBtnBg,
|
||||
color: oc.bookBtnFg, fontWeight: 800, fontSize: 16, letterSpacing: 0.02,
|
||||
boxShadow: '0 6px 16px rgba(76, 154, 154, 0.25)',
|
||||
border: '1px solid rgba(76,154,154,0.2)',
|
||||
}}>
|
||||
<I.calendar size={21} sw={2} style={{ color: oc.bookBtnFg }} />
|
||||
Записаться на приём
|
||||
</Link>
|
||||
</div>
|
||||
<div style={{ height: 20 }} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: Z_FOOTER_BAR,
|
||||
background: 'rgba(255,255,255,0.94)',
|
||||
backdropFilter: 'blur(16px) saturate(180%)',
|
||||
WebkitBackdropFilter: 'blur(16px) saturate(180%)',
|
||||
borderTop: '1px solid #E8E8E8',
|
||||
boxShadow: '0 -4px 24px rgba(15,30,40,0.06)',
|
||||
background: oc.card,
|
||||
borderTop: `1px solid ${oc.border}`,
|
||||
boxShadow: 'none',
|
||||
}}>
|
||||
<div style={{ padding: '10px 16px 6px' }}>
|
||||
<Link to="/" className="press" style={{
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 10,
|
||||
width: '100%', padding: '15px 16px', borderRadius: 16, textDecoration: 'none',
|
||||
background: oc.bookBtnBg,
|
||||
color: oc.bookBtnFg, fontWeight: 800, fontSize: 16, letterSpacing: 0.02,
|
||||
boxShadow: '0 6px 18px rgba(0, 28, 34, 0.1)',
|
||||
border: '1px solid rgba(255,255,255,0.35)',
|
||||
}}>
|
||||
<I.calendar size={21} sw={2} style={{ color: oc.bookBtnFg }} />
|
||||
Записаться на приём
|
||||
</Link>
|
||||
</div>
|
||||
<OclinicaTabBar />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user