From 9d0e62b9529c0c6eb0b450cb243f7490cfef450f Mon Sep 17 00:00:00 2001 From: gnezim Date: Wed, 15 Apr 2026 19:34:45 +0300 Subject: [PATCH] Wrap Schedule page in PageLayout with tabs and Angular-matching styles Schedule start page now uses PageLayout with PageTabs (schedule tab active), filter form in content-left column, and the info section with titles-container and PopularRequests in the main content area. SCSS matches Angular start.scss. --- .../components/ScheduleStartPage.scss | 190 +++++++++----- .../schedule/components/ScheduleStartPage.tsx | 242 +++++++++++------- 2 files changed, 279 insertions(+), 153 deletions(-) diff --git a/src/features/schedule/components/ScheduleStartPage.scss b/src/features/schedule/components/ScheduleStartPage.scss index 4fdb0240..88b9271c 100644 --- a/src/features/schedule/components/ScheduleStartPage.scss +++ b/src/features/schedule/components/ScheduleStartPage.scss @@ -1,47 +1,147 @@ @use "../../../styles/variables" as vars; +@use "../../../styles/fonts" as fonts; @use "../../../styles/colors" as colors; @use "../../../styles/screen" as screen; +@use "../../../styles/shadows" as shadows; -.schedule-start { - &__title { - font-size: 22px; - margin: 0 0 vars.$space-xl; - } +.schedule-start-page { + section.frame { + padding: 0; - &__form { - display: flex; - flex-direction: column; - gap: vars.$space-m; - - .card { - display: flex; - flex-direction: column; + h2 { + padding: 50px; + padding-bottom: 20px; } - @include screen.mobile { - .card { - padding: vars.$space-xl vars.$space-xl 0; + .titles-container { + display: flex; + flex-direction: row; + flex-wrap: wrap; + padding: 0 50px; + padding-bottom: 50px; + + .title { + width: 50%; + padding: 30px; + padding-right: 50px; + padding-left: 65px; + background-repeat: no-repeat; + background-position: left center; + + a { + cursor: default; + font-size: fonts.$font-size-xl; + } + + div { + color: colors.$gray; + padding-top: vars.$space-s; + } + + &.title1 { + background-image: url('/assets/img/schedule-title-icon-1.svg'); + } + + &.title2 { + background-image: url('/assets/img/schedule-title-icon-2.svg'); + } + + &.title3 { + background-image: url('/assets/img/schedule-title-icon-3.svg'); + } + + &.title4 { + background-image: url('/assets/img/schedule-title-icon-4.svg'); + } } } } - &__field { + @media (max-width: vars.$media-breakpoint-mobile) { + section.frame h2 { + padding: 20px; + font-size: 20px; + line-height: 28px; + padding-bottom: 0px; + padding-top: 30px; + } + + .titles-container { + padding: 20px !important; + padding-top: 0 !important; + + div.title { + width: 100% !important; + padding: 20px !important; + padding-left: 50px !important; + background-size: 35px auto !important; + + a { + font-size: 16px; + } + } + } + } + + .page-title { + width: auto; + display: inline-block; + max-width: 100%; + white-space: normal !important; + } + + h1.text--white { + @include fonts.font-overflow(); + + @include screen.smTablet { + font-size: fonts.$font-size-xxxl--tablet; + margin-bottom: vars.$space-m + vars.$space-s; + overflow: visible; + white-space: normal; + } + + @include screen.mobile { + font-size: fonts.$font-size-xxxl--mobile; + margin-bottom: vars.$space-m + vars.$space-s; + margin-top: vars.$space-m; + overflow: visible; + white-space: normal; + } + } + + // Schedule filter panel in content-left column + .schedule-start__form { + @include shadows.box-shadow-small; + background-color: colors.$white; + border-radius: vars.$border-radius; + padding: vars.$space-xl; + display: flex; + flex-direction: column; + gap: vars.$space-m; + } + + .schedule-start__field { display: flex; flex-direction: column; gap: vars.$space-s; label { font-weight: 500; + @include fonts.font-small(colors.$gray); + margin-bottom: vars.$label-margin-bottom; } input[type="text"], input[type="date"] { + @include shadows.control-border-shadow(); height: vars.$standard-button-height; padding: 0 vars.$space-l; - border: 1px solid colors.$border-input; - border-radius: vars.$border-radius; - font-size: 16px; - transition: border-color 0.2s; + font-size: fonts.$font-size-l; + font-weight: fonts.$font-regular; + color: colors.$text-color; + width: 100%; + transition-duration: 0.2s; + @include fonts.font-overflow(); &:focus { outline: none; @@ -51,17 +151,21 @@ } } - &__submit { + .schedule-start__submit { + margin-top: vars.$space-xl; + width: 100%; height: vars.$standard-button-height; - background-color: colors.$blue-light; + background-color: colors.$blue; color: colors.$white; border: none; border-radius: vars.$border-radius; - font-size: 16px; cursor: pointer; + transition-duration: 0.2s; + font-weight: fonts.$font-bold; + font-size: fonts.$font-size-m; &:hover { - background-color: colors.$blue-light--hover; + background-color: colors.$blue--hover; } &:focus { @@ -69,39 +173,3 @@ } } } - -.schedule-home-page-header { - display: flex; - margin: vars.$space-xl; - - @include screen.mobile { - margin-left: 0; - margin-right: 0; - } -} - -.schedule-home-page-header-border { - border-bottom: 1px solid colors.$border; - - @include screen.mobile { - display: none; - } -} - -.schedule-controls { - .card { - display: flex; - flex-direction: column; - } - - @include screen.mobile { - .card { - padding: vars.$space-xl vars.$space-xl 0; - } - - &__tabs { - display: flex; - flex-direction: column; - } - } -} diff --git a/src/features/schedule/components/ScheduleStartPage.tsx b/src/features/schedule/components/ScheduleStartPage.tsx index 19e3d158..13b16c21 100644 --- a/src/features/schedule/components/ScheduleStartPage.tsx +++ b/src/features/schedule/components/ScheduleStartPage.tsx @@ -9,6 +9,11 @@ import { type FC, useState, useCallback, type FormEvent } from "react"; import { useNavigate, useParams } from "@modern-js/runtime/router"; +import { useTranslation } from "@/i18n/provider.js"; +import { PageLayout } from "@/ui/layout/PageLayout.js"; +import { PageTabs } from "@/ui/layout/PageTabs.js"; +import { PopularRequestsPanel } from "@/features/popular-requests/components/PopularRequestsPanel.js"; +import type { PopularRequest } from "@/features/popular-requests/types.js"; import { buildScheduleUrl } from "../url.js"; import "./ScheduleStartPage.scss"; @@ -43,6 +48,7 @@ function addDaysToDateInput(value: string, days: number): string { export const ScheduleStartPage: FC = () => { const navigate = useNavigate(); + const { t } = useTranslation(); const routeParams = useParams<{ lang: string }>(); const lang = routeParams.lang ?? "ru"; @@ -92,109 +98,161 @@ export const ScheduleStartPage: FC = () => { [departureAirport, arrivalAirport, dateFrom, dateTo, isRoundTrip, returnDateFrom, returnDateTo, navigate, lang], ); - return ( -
-

Flight Schedule

+ const handlePopularRequestClick = useCallback((_request: PopularRequest) => { + // Navigation handled by PopularRequestItem internally + }, []); -
-
- + const scheduleFilter = ( + +
+ + setDepartureAirport(e.target.value)} + data-testid="departure-input" + /> +
+ +
+ + setArrivalAirport(e.target.value)} + data-testid="arrival-input" + /> +
+ +
+ + setDateFrom(e.target.value)} + data-testid="date-from-input" + /> +
+ +
+ + setDateTo(e.target.value)} + data-testid="date-to-input" + /> +
+ +
+
+ Round trip + +
-
- - setArrivalAirport(e.target.value)} - data-testid="arrival-input" - /> -
- -
- - setDateFrom(e.target.value)} - data-testid="date-from-input" - /> -
- -
- - setDateTo(e.target.value)} - data-testid="date-to-input" - /> -
- -
-
- {isRoundTrip && ( - <> -
- - setReturnDateFrom(e.target.value)} - data-testid="return-date-from-input" - /> +
+ + setReturnDateTo(e.target.value)} + data-testid="return-date-to-input" + /> +
+ + )} + + + + ); + + return ( +
+ + } + title={ +

+ {t("SCHEDULE.TITLE")} +

+ } + contentLeft={scheduleFilter} + > +
+

{t("SCHEDULE.SCHEDULE-START")}

+ +
+
+ {t("SCHEDULE.SCHEDULE-START-TITLE1")} +
+ {t("SCHEDULE.SCHEDULE-START-TITLE1-DESCRIPTION")} +
-
- - setReturnDateTo(e.target.value)} - data-testid="return-date-to-input" - /> +
+ {t("SCHEDULE.SCHEDULE-START-TITLE2")} +
+ {t("SCHEDULE.SCHEDULE-START-TITLE2-DESCRIPTION")} +
- - )} - - +
+ {t("SCHEDULE.SCHEDULE-START-TITLE3")} +
+ {t("SCHEDULE.SCHEDULE-START-TITLE3-DESCRIPTION")} +
+
+ +
+ {t("SCHEDULE.SCHEDULE-START-TITLE4")} +
+ {t("SCHEDULE.SCHEDULE-START-TITLE4-DESCRIPTION")} +
+
+
+ + +
+
); };