- Introduced `PageSeo` component for managing page metadata for social sharing. - Created Open Graph image templates using SVG and static fonts for better visual representation. - Implemented service alert management with functions to check active alerts and format route numbers. - Added utility functions for generating and watching alert validity. - Developed a script to generate Open Graph images dynamically based on page content. - Included tests for service alert functionalities to ensure correctness and reliability.
180 lines
4.9 KiB
JavaScript
180 lines
4.9 KiB
JavaScript
import { createElement as h } from 'react';
|
|
|
|
// ImageResponse uses flex and inline styles, independently of browser CSS,
|
|
// animation and the landing's Webpack loaders.
|
|
const box = (style, ...children) =>
|
|
h('div', { style: { display: 'flex', ...style } }, ...children);
|
|
const picture = (src, width, height, style = {}) =>
|
|
h('img', { src, width, height, style });
|
|
|
|
export function createOgImage(page, locale, assets) {
|
|
const copy = page[locale];
|
|
const handwritten = ['schedule', 'community'].includes(page.illustration);
|
|
const privacy = page.illustration === 'privacy';
|
|
const accent = page.illustration === 'terms' ? '#715573' : '#1d4fac';
|
|
const headingSize = locale === 'ru' && privacy ? 58 : 76;
|
|
const secondSize = locale === 'ru' && privacy ? 52 : handwritten ? 100 : 76;
|
|
const illustrations = {
|
|
schedule: assets.logo,
|
|
community: assets.love,
|
|
privacy: assets.shield,
|
|
terms: assets.note,
|
|
};
|
|
|
|
return box(
|
|
{
|
|
position: 'relative',
|
|
width: '100%',
|
|
height: '100%',
|
|
padding: 32,
|
|
color: '#242424',
|
|
backgroundColor: '#fff',
|
|
fontFamily: 'Manrope',
|
|
fontWeight: 600,
|
|
},
|
|
box(
|
|
{
|
|
position: 'relative',
|
|
width: '100%',
|
|
height: '100%',
|
|
borderRadius: 36,
|
|
overflow: 'hidden',
|
|
backgroundColor: '#f5f7fc',
|
|
},
|
|
picture(assets.background, 1136, 566, {
|
|
position: 'absolute',
|
|
left: 0,
|
|
top: 0,
|
|
}),
|
|
picture(assets.star6, 350, 365, {
|
|
position: 'absolute',
|
|
right: -60,
|
|
top: 122,
|
|
opacity: 0.72,
|
|
transform: 'rotate(16deg)',
|
|
}),
|
|
picture(assets.star5, 170, 170, {
|
|
position: 'absolute',
|
|
right: 237,
|
|
bottom: 21,
|
|
opacity: 0.48,
|
|
transform: 'rotate(-15deg)',
|
|
}),
|
|
picture(assets.thinStar, 148, 148, {
|
|
position: 'absolute',
|
|
left: -71,
|
|
bottom: -60,
|
|
opacity: 0.32,
|
|
transform: 'rotate(10deg)',
|
|
}),
|
|
box(
|
|
{
|
|
position: 'relative',
|
|
flexDirection: 'column',
|
|
justifyContent: 'space-between',
|
|
width: '100%',
|
|
height: '100%',
|
|
padding: '38px 44px',
|
|
},
|
|
box(
|
|
{ alignItems: 'center', justifyContent: 'space-between' },
|
|
box(
|
|
{ alignItems: 'center', gap: 12 },
|
|
picture(assets.logo, 48, 48),
|
|
h('span', { style: { fontSize: 32, fontWeight: 800 } }, 'ridebus')
|
|
),
|
|
box(
|
|
{
|
|
padding: '12px 22px',
|
|
borderRadius: 40,
|
|
fontSize: 18,
|
|
color: accent,
|
|
backgroundColor: '#ffffffb3',
|
|
},
|
|
copy.label
|
|
)
|
|
),
|
|
box(
|
|
{ flexDirection: 'column', width: 730, marginTop: 10 },
|
|
h(
|
|
'div',
|
|
{
|
|
style: {
|
|
fontSize: headingSize,
|
|
lineHeight: 1.16,
|
|
fontWeight: 800,
|
|
letterSpacing: '-2.5px',
|
|
},
|
|
},
|
|
copy.heading[0]
|
|
),
|
|
h(
|
|
'div',
|
|
{
|
|
style: {
|
|
fontFamily: handwritten ? 'Caveat' : 'Manrope',
|
|
fontSize: secondSize,
|
|
fontWeight: handwritten ? 700 : 800,
|
|
lineHeight: handwritten ? 1.1 : 1.2,
|
|
letterSpacing: handwritten ? '-1px' : '-2px',
|
|
color: handwritten ? '#715573' : accent,
|
|
marginTop: handwritten ? -2 : 4,
|
|
},
|
|
},
|
|
copy.heading[1]
|
|
),
|
|
box(
|
|
{
|
|
marginTop: 22,
|
|
maxWidth: 665,
|
|
fontSize: 24,
|
|
lineHeight: 1.5,
|
|
color: '#526079',
|
|
},
|
|
copy.caption
|
|
)
|
|
),
|
|
box(
|
|
{ alignItems: 'center', justifyContent: 'space-between' },
|
|
box(
|
|
{ gap: 10 },
|
|
...copy.tags.map((tag) =>
|
|
box(
|
|
{
|
|
padding: '10px 18px',
|
|
borderRadius: 18,
|
|
backgroundColor: '#ffffffb3',
|
|
fontSize: 17,
|
|
color: '#526079',
|
|
},
|
|
tag
|
|
)
|
|
)
|
|
),
|
|
h('span', { style: { fontSize: 20, color: accent } }, 'ridebus.by')
|
|
)
|
|
),
|
|
box(
|
|
{
|
|
position: 'absolute',
|
|
right: 44,
|
|
top: 197,
|
|
width: 236,
|
|
height: 236,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
borderRadius: 60,
|
|
backgroundColor: '#ffffffdb',
|
|
border: '2px solid #ffffff',
|
|
transform: 'rotate(-9deg)',
|
|
},
|
|
picture(
|
|
illustrations[page.illustration],
|
|
page.illustration === 'schedule' ? 164 : 126,
|
|
page.illustration === 'schedule' ? 164 : 126
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|