Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Fixed

- **Address search** перестал «перепрыгивать» в другой город при выборе подсказки. Координаты выбранной подсказки теперь берутся из `SuggestResult.coords` (их кладёт `ymaps3.search` в `suggestAddresses`). Раньше после клика делался повторный resolve по `sug.uri`, в котором хранился только `title` без региона из `subtitle` — Yandex без региона возвращал первый попавшийся объект (например, «Ломоносова 9 Санкт-Петербург» уходил в Великий Новгород). Заодно удалены ставшие мёртвыми `useResolveCoordinates` и `geocodeByUri` (`shared/lib/yandex/geocoder.ts`); экземпляр `isResolving` в загрузочном статусе Desktop-варианта тоже снят.

## [1.0.0-mvp] — Phase 5 verification complete

Final MVP release. Merge from `feat/mvp-rewrite` → `main`.
Expand Down
6 changes: 4 additions & 2 deletions nginx-security-headers.conf
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
# грузится fetch()'ем; MSW service-worker (mock) переотправляет его как
# fetch → правило connect-src, не script-src. Без этого — белый экран.
# - *.parktrack.live — prod (api.parktrack.live) + dev (api.dev.parktrack.live)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-eval' https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://yastatic.net https://suggest-maps.yandex.ru; connect-src 'self' https://*.parktrack.live https://api.parktrack.live https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://*.maps.yandex.net https://yastatic.net https://suggest-maps.yandex.ru https://search-maps.yandex.ru https://geocode-maps.yandex.ru https://api.routing.yandex.net; style-src 'self' 'unsafe-inline' https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://yastatic.net; img-src 'self' data: blob: https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://*.maps.yandex.net https://yastatic.net; worker-src 'self' data: blob: https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://yastatic.net; frame-ancestors 'self' https://parktrack.live https://*.parktrack.live;" always;
add_header X-Content-Type-Options "nosniff" always;
# - http://localhost:8000 / http://127.0.0.1:8000 — локальный api-server (dev/demo
# compose-сборка с VITE_API_BASE_URL=http://localhost:8000); 'self' покрывает
# только same-origin (порт 80/13000), на :8000 нужен явный allow.
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-eval' https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://yastatic.net https://*.yastatic.net https://suggest-maps.yandex.ru https://cdn.jsdelivr.net; connect-src 'self' http://localhost:8000 http://127.0.0.1:8000 https://*.parktrack.live https://api.parktrack.live https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://*.maps.yandex.net https://yastatic.net https://*.yastatic.net https://suggest-maps.yandex.ru https://search-maps.yandex.ru https://geocode-maps.yandex.ru https://api.routing.yandex.net https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://yastatic.net https://*.yastatic.net https://cdn.jsdelivr.net; img-src 'self' data: blob: https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://*.maps.yandex.net https://yastatic.net https://*.yastatic.net; worker-src 'self' data: blob: https://api-maps.yandex.ru https://*.api-maps.yandex.ru https://yastatic.net https://*.yastatic.net; frame-ancestors 'self' https://parktrack.live https://*.parktrack.live;" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
7 changes: 7 additions & 0 deletions src/entities/filters/model/filter-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export function readFiltersFromStorage(): Partial<ZoneFilters> {
const hnf = ssGet('hideNoFree');
if (hnf !== null) r.hideNoFree = hnf === '1';

const mfc = ssGet('minFreeCount');
if (mfc !== null) {
const n = Number(mfc);
if (Number.isFinite(n) && n >= 0) r.minFreeCount = Math.floor(n);
}

const mc = ssGet('minConf');
if (mc !== null) {
const n = Number(mc);
Expand Down Expand Up @@ -89,6 +95,7 @@ export function writeFilterToStorage<K extends keyof ZoneFilters>(
case 'hideInactive':
serialized = (value as boolean) ? '1' : '0';
break;
case 'minFreeCount':
case 'minConf':
serialized = String(value as number);
break;
Expand Down
6 changes: 4 additions & 2 deletions src/entities/filters/model/filter.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const ALL_LOCATION_TYPES: readonly LocationType[] = [

export interface ZoneFilters {
hideNoFree: boolean; // FILTER-01 default false
minFreeCount: number;
minConf: number; // FILTER-02 default 0 (no min)
maxPay: number | null; // FILTER-03 default null (no max)
hidePrivate: boolean; // FILTER-04 default false
Expand All @@ -24,6 +25,7 @@ export interface ZoneFilters {

export const DEFAULT_FILTERS: ZoneFilters = {
hideNoFree: false,
minFreeCount: 0,
minConf: 0,
maxPay: null,
hidePrivate: false,
Expand All @@ -32,15 +34,15 @@ export const DEFAULT_FILTERS: ZoneFilters = {
hideInactive: true,
};

// FILTER-09: сколько фильтров не в дефолте (для badge-count «Активно: N»).
export function countActive(f: ZoneFilters): number {
let n = 0;
if (f.hideNoFree !== DEFAULT_FILTERS.hideNoFree) n++;
if (f.minFreeCount !== DEFAULT_FILTERS.minFreeCount) n++;
if (f.minConf !== DEFAULT_FILTERS.minConf) n++;
if (f.maxPay !== DEFAULT_FILTERS.maxPay) n++;
if (f.hidePrivate !== DEFAULT_FILTERS.hidePrivate) n++;
if (f.hideAccessible !== DEFAULT_FILTERS.hideAccessible) n++;
if (f.locationType.length !== 0) n++;
if (f.hideInactive !== DEFAULT_FILTERS.hideInactive) n++;
return n;
}
}
Loading
Loading