feat: implement BoardFlightBody with detailed flight information

This commit is contained in:
gnezim
2026-04-05 21:13:12 +03:00
parent 0366db1a2f
commit 49c696610c
2 changed files with 274 additions and 21 deletions
@@ -2,25 +2,112 @@
padding: 16px; padding: 16px;
background: #fafafa; background: #fafafa;
border-top: 1px solid #e0e0e0; border-top: 1px solid #e0e0e0;
display: flex;
flex-direction: column;
gap: 16px;
}
.board-flight-body__content {
display: flex;
flex-direction: column;
gap: 16px;
} }
.board-flight-body__section { .board-flight-body__section {
margin-bottom: 16px; display: flex;
flex-direction: column;
gap: 8px;
}
&:last-child { .board-flight-body__section-title {
margin-bottom: 0; margin: 0;
font-size: 13px;
font-weight: 600;
color: #666;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.board-flight-body__info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 12px;
@media (max-width: 768px) {
grid-template-columns: repeat(2, 1fr);
} }
h3 { @media (max-width: 480px) {
margin: 0 0 8px 0; grid-template-columns: 1fr;
font-size: 14px; }
font-weight: 600; }
color: #333;
} .board-flight-body__info-item {
display: flex;
p { flex-direction: column;
margin: 0; gap: 4px;
color: #666; padding: 8px;
font-size: 14px; background: white;
border-radius: 4px;
border: 1px solid #e0e0e0;
}
.board-flight-body__label {
font-size: 11px;
color: #999;
text-transform: uppercase;
font-weight: 500;
}
.board-flight-body__value {
font-size: 14px;
color: #333;
font-weight: 500;
display: flex;
flex-direction: column;
gap: 2px;
}
.board-flight-body__city {
font-size: 12px;
color: #999;
font-weight: 400;
}
.board-flight-body__actual {
font-size: 12px;
color: #f57c00;
font-weight: 500;
}
.board-flight-body__codesharing-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.board-flight-body__codeshare-badge {
padding: 4px 10px;
background: #e3f2fd;
color: #1565c0;
border-radius: 4px;
font-size: 12px;
font-weight: 500;
}
.board-flight-body__actions {
display: flex;
gap: 8px;
justify-content: flex-end;
padding-top: 8px;
border-top: 1px solid #e0e0e0;
:global {
.p-button {
&.p-button-sm {
padding: 6px 12px;
font-size: 12px;
}
}
} }
} }
@@ -1,20 +1,186 @@
import React from 'react' import React from 'react'
import { Button } from 'primereact/button'
import { useNavigate } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import './board-flight-body.scss' import './board-flight-body.scss'
export interface BoardFlightBodyProps { export interface BoardFlightBodyProps {
flight: any flight: {
id: string
flightNumber: string
departure: {
airport: string
city: string
scheduled: string
actual?: string
terminal?: string
gate?: string
}
arrival: {
airport: string
city: string
scheduled: string
actual?: string
terminal?: string
gate?: string
}
boarding?: {
time: string
gate: string
}
deboarding?: {
time: string
gate: string
}
codesharing?: string[]
}
} }
export const BoardFlightBody: React.FC<BoardFlightBodyProps> = ({ flight }) => { export const BoardFlightBody: React.FC<BoardFlightBodyProps> = ({ flight }) => {
const navigate = useNavigate()
const { t } = useTranslation()
const handleViewDetails = () => {
// Navigate to full flight details page
const params = btoa(JSON.stringify({ id: flight.id, flightNumber: flight.flightNumber }))
navigate(`/onlineboard/${params}`)
}
return ( return (
<div className="board-flight-body" data-testid={`flight-body-${flight.id}`}> <div className="board-flight-body" data-testid={`flight-body-${flight.id}`}>
<div className="board-flight-body__section"> <div className="board-flight-body__content">
<h3>Departure</h3> {/* Departure Section */}
<p>{flight.departure.airport} - {flight.departure.city}</p> <div className="board-flight-body__section">
<h4 className="board-flight-body__section-title">{t('SHARED.DEPARTURE')}</h4>
<div className="board-flight-body__info-grid">
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.AIRPORT')}</span>
<span className="board-flight-body__value">
{flight.departure.airport}
<span className="board-flight-body__city">{flight.departure.city}</span>
</span>
</div>
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.TIME')}</span>
<span className="board-flight-body__value">
{flight.departure.scheduled}
{flight.departure.actual && (
<span className="board-flight-body__actual">{flight.departure.actual}</span>
)}
</span>
</div>
{flight.departure.terminal && (
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.TERMINAL')}</span>
<span className="board-flight-body__value">{flight.departure.terminal}</span>
</div>
)}
{flight.departure.gate && (
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.GATE')}</span>
<span className="board-flight-body__value">{flight.departure.gate}</span>
</div>
)}
</div>
</div>
{/* Boarding Section */}
{flight.boarding && (
<div className="board-flight-body__section">
<h4 className="board-flight-body__section-title">{t('BOARD.BOARDING')}</h4>
<div className="board-flight-body__info-grid">
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.TIME')}</span>
<span className="board-flight-body__value">{flight.boarding.time}</span>
</div>
{flight.boarding.gate && (
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.GATE')}</span>
<span className="board-flight-body__value">{flight.boarding.gate}</span>
</div>
)}
</div>
</div>
)}
{/* Arrival Section */}
<div className="board-flight-body__section">
<h4 className="board-flight-body__section-title">{t('SHARED.ARRIVAL')}</h4>
<div className="board-flight-body__info-grid">
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.AIRPORT')}</span>
<span className="board-flight-body__value">
{flight.arrival.airport}
<span className="board-flight-body__city">{flight.arrival.city}</span>
</span>
</div>
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.TIME')}</span>
<span className="board-flight-body__value">
{flight.arrival.scheduled}
{flight.arrival.actual && (
<span className="board-flight-body__actual">{flight.arrival.actual}</span>
)}
</span>
</div>
{flight.arrival.terminal && (
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.TERMINAL')}</span>
<span className="board-flight-body__value">{flight.arrival.terminal}</span>
</div>
)}
{flight.arrival.gate && (
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.GATE')}</span>
<span className="board-flight-body__value">{flight.arrival.gate}</span>
</div>
)}
</div>
</div>
{/* Deboarding Section */}
{flight.deboarding && (
<div className="board-flight-body__section">
<h4 className="board-flight-body__section-title">{t('BOARD.DEBOARDING')}</h4>
<div className="board-flight-body__info-grid">
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.TIME')}</span>
<span className="board-flight-body__value">{flight.deboarding.time}</span>
</div>
{flight.deboarding.gate && (
<div className="board-flight-body__info-item">
<span className="board-flight-body__label">{t('SHARED.GATE')}</span>
<span className="board-flight-body__value">{flight.deboarding.gate}</span>
</div>
)}
</div>
</div>
)}
{/* Codesharing Section */}
{flight.codesharing && flight.codesharing.length > 0 && (
<div className="board-flight-body__section">
<h4 className="board-flight-body__section-title">{t('BOARD.CODESHARING')}</h4>
<div className="board-flight-body__codesharing-list">
{flight.codesharing.map((code, idx) => (
<span key={idx} className="board-flight-body__codeshare-badge">
{code}
</span>
))}
</div>
</div>
)}
</div> </div>
<div className="board-flight-body__section">
<h3>Arrival</h3> {/* Action Buttons */}
<p>{flight.arrival.airport} - {flight.arrival.city}</p> <div className="board-flight-body__actions">
<Button
label={t('BOARD.VIEW_DETAILS')}
icon="pi pi-arrow-right"
onClick={handleViewDetails}
className="p-button-sm"
data-testid={`flight-details-button-${flight.id}`}
/>
</div> </div>
</div> </div>
) )