improvements

This commit is contained in:
2026-10-02 20:31:49 +03:00
parent 5ad60b819a
commit 6460846134
79 changed files with 21275 additions and 7875 deletions

View File

@@ -0,0 +1,114 @@
.card {
--on-background: #2c4678;
--on-background-secondary: #455e91;
--background: #d8e2ff;
position: relative;
}
.content {
position: relative;
margin-top: 32px;
}
.star {
width: 300px;
height: 300px;
position: absolute;
right: -140px;
bottom: -130px;
color: #aec6ff;
transform: rotate(-15deg);
pointer-events: none;
}
.steps {
list-style: none;
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 32px;
position: relative;
li {
display: flex;
align-items: flex-start;
gap: 16px;
min-width: 0;
}
h4 {
font-size: 1.125rem;
font-weight: 800;
margin-bottom: 6px;
}
p {
color: var(--on-background-secondary);
font-size: 0.95rem;
line-height: 1.6;
}
}
.number {
flex-shrink: 0;
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
background: #f3f3fa;
border-radius: 16px;
font-size: 1.25rem;
font-weight: 800;
}
.contact {
position: relative;
margin-top: 36px;
}
.handwritten {
display: inline-block;
font-size: 2rem;
font-weight: 600;
transform: rotate(-3deg);
}
.links {
display: flex;
gap: 16px;
flex-wrap: wrap;
}
.link {
--background: #fff;
flex: 1 1 260px;
max-width: 380px;
a:focus-visible {
display: block;
border-radius: 16px;
outline: 3px solid #2c4678;
outline-offset: 3px;
}
}
@media (max-width: 980px) {
.steps {
grid-template-columns: minmax(0, 1fr);
gap: 24px;
}
}
@media (max-width: 500px) {
.card {
padding: 24px;
}
.links {
gap: 0;
}
.link {
max-width: none;
}
}

View File

@@ -0,0 +1,97 @@
import clsx from 'clsx';
import { Card, CardLink } from '@/components/card';
import Star from '@/assets/images/thick-round-star-6.svg';
import useLocale, { LocalesMap } from '@/utils/useLocale';
import { caveat } from '@/styles/fonts';
import styles from './addCityCard.module.scss';
const locales: LocalesMap = {
ru: {
title: 'Помогите добавить свой город',
description:
'Знаете, где найти расписание транспорта в вашем городе? Поделитесь источником — это поможет расширить RideBus.',
city: 'Название города',
cityDescription: 'Расскажите, для какого города нужно расписание.',
source: 'Источник расписания',
sourceDescription:
'Пришлите ссылку на сайт перевозчика или актуальное расписание.',
details: 'Полезные подробности',
detailsDescription:
'Если знаете, добавьте номера маршрутов и названия остановок.',
handwritten: 'Начнём с вашего города',
contact: 'Напишите в Telegram',
contactDescription: 'Пришлите название города и источник расписания',
email: 'Или напишите на почту',
emailSubject: 'Новый город для RideBus',
emailBody:
'Город: \nИсточник расписания: \nМаршруты и остановки (если известны): \n',
},
en: {
title: 'Help add your city',
description:
'Know where to find your city’s transport timetable? Share a source to help bring RideBus to more cities.',
city: 'Your city',
cityDescription: 'Tell us which city needs a timetable.',
source: 'A timetable source',
sourceDescription:
'Send a link to the transport operator’s website or a current timetable.',
details: 'Helpful details',
detailsDescription:
'Include route numbers and stop names if you know them.',
handwritten: 'Let’s start with your city',
contact: 'Get in touch on Telegram',
contactDescription: 'Send your city’s name and a timetable source',
email: 'Or send an email',
emailSubject: 'A new city for RideBus',
emailBody: 'City: \nTimetable source: \nRoutes and stops (if known): \n',
},
};
export function AddCityCard() {
const t = useLocale(locales);
const email = `mailto:xtimms@live.com?subject=${encodeURIComponent(t('emailSubject'))}&body=${encodeURIComponent(t('emailBody'))}`;
return (
<section aria-label={t('title')}>
<Card
className={styles.card}
title={t('title')}
subtitle={t('description')}
classes={{ content: styles.content }}
>
<Star className={styles.star} aria-hidden="true" />
<ol className={styles.steps}>
{['city', 'source', 'details'].map((step, index) => (
<li key={step}>
<span className={styles.number} aria-hidden="true">
{index + 1}
</span>
<div>
<h4>{t(step)}</h4>
<p>{t(`${step}Description`)}</p>
</div>
</li>
))}
</ol>
<div className={styles.contact}>
{/* <span className={clsx(styles.handwritten, caveat.className)}>
{t('handwritten')}
</span> */}
<div className={styles.links}>
<CardLink
title={t('contact')}
hrefTitle={t('contactDescription')}
href="https://t.me/xtimms"
className={styles.link}
/>
<CardLink
title={t('email')}
hrefTitle="xtimms@live.com"
href={email}
className={styles.link}
/>
</div>
</div>
</Card>
</section>
);
}

View File

@@ -55,7 +55,7 @@
position: relative;
display: inline;
div {
.arrowImage {
position: absolute;
top: 13px;
left: 26px;
@@ -179,7 +179,7 @@
line-height: 170%;
.contributeArrow {
div {
.arrowImage {
top: 8px;
}
svg {
@@ -203,7 +203,7 @@
.description {
.contributeArrow {
div {
.arrowImage {
top: 10px;
}
svg {
@@ -213,4 +213,4 @@
}
}
}
}

View File

@@ -39,7 +39,7 @@ export const locales: LocalesMap = {
};
function Arrow() {
const rootRef = useRef<HTMLDivElement>(null);
const rootRef = useRef<HTMLSpanElement>(null);
const [isInvertArrow, setIsInvertArrow] = useState(false);
const breakpoint640 = useMediaQuery('(max-width: 640px)');
const breakpoint800 = useMediaQuery('(max-width: 800px)');
@@ -79,9 +79,9 @@ function Arrow() {
return (
<span ref={rootRef} className={styles.contributeArrow}>
<span style={{ width: '140px', display: 'inline-block' }} />
<div style={{ left }}>
<span className={styles.arrowImage} style={{ left }}>
{isInvertArrow ? <ContributeArrowInvert /> : <ContributeArrow />}
</div>
</span>
</span>
)
}
@@ -123,4 +123,4 @@ export function Header() {
</div>
</header>
);
}
}

View File

@@ -48,13 +48,9 @@ export function ShareCard() {
>
</Card>
);
if (typeof window !== 'undefined' && (navigator.share as any)) {
return (
<CursorEffect cursorPadding={8} cursorBorderRadius={36}>
{ShareCard}
</CursorEffect>
);
} else {
return ShareCard;
}
}
return (
<CursorEffect cursorPadding={8} cursorBorderRadius={36}>
{ShareCard}
</CursorEffect>
);
}