Files
BIU_System_Rezerwacji/src/pages/ReservationsPage.module.scss
Krzysztof Cieślik 2593e81498 Inicjalna wersja systemu zarządzania rezerwacjami (RMS)
SPA zbudowane w React 19 + Vite 8 z pełnym zestawem funkcjonalności:
autentykacja z 2FA, kreator rezerwacji, panel admina, analityka,
GraphQL (Apollo Client + SchemaLink), React Query, Storybook,
testy jednostkowe (Vitest + RTL) i e2e (Playwright).
2026-06-21 06:23:36 +02:00

478 lines
12 KiB
SCSS

@use '../styles/variables' as *;
.rp {
min-height: 100vh;
background: var(--clr-bg);
// ── Header ────────────────────────────────────────────────────────────────
&__header {
background: var(--clr-surface);
border-bottom: 1px solid var(--clr-border);
box-shadow: $shadow-sm;
}
&__header-inner {
max-width: $container-max-width;
margin-inline: auto;
padding: $spacing-4 $spacing-6;
display: flex;
align-items: center;
justify-content: space-between;
gap: $spacing-4;
}
&__header-left {
display: flex;
align-items: center;
gap: $spacing-5;
}
&__back {
display: inline-flex;
align-items: center;
gap: $spacing-1;
font-size: $font-size-sm;
font-weight: $font-weight-medium;
color: var(--clr-text-secondary);
text-decoration: none;
padding: $spacing-1 $spacing-2;
border-radius: $radius-base;
transition: color $transition-fast, background $transition-fast;
white-space: nowrap;
&:hover {
color: var(--clr-text);
background: var(--clr-surface-raised);
}
}
&__title {
display: flex;
align-items: center;
gap: $spacing-2;
font-size: $font-size-xl;
font-weight: $font-weight-semibold;
color: var(--clr-text);
margin: 0;
}
&__subtitle {
font-size: $font-size-sm;
color: var(--clr-text-secondary);
margin: $spacing-1 0 0;
}
&__header-actions {
display: flex;
align-items: center;
gap: $spacing-3;
}
&__logout {
padding: $spacing-2 $spacing-4;
border: 1px solid var(--clr-border);
border-radius: $radius-base;
background: transparent;
font-size: $font-size-sm;
font-weight: $font-weight-medium;
font-family: $font-family-base;
color: var(--clr-text-secondary);
cursor: pointer;
transition: background $transition-fast, color $transition-fast;
&:hover { background: var(--clr-surface-raised); color: var(--clr-text); }
}
// ── Main ──────────────────────────────────────────────────────────────────
&__main {
max-width: 780px;
margin-inline: auto;
padding: $spacing-8 $spacing-6;
}
// ── Filter tabs ───────────────────────────────────────────────────────────
&__tabs {
display: flex;
gap: $spacing-2;
margin-bottom: $spacing-6;
border-bottom: 1px solid var(--clr-border);
padding-bottom: 0;
}
&__tab {
display: inline-flex;
align-items: center;
gap: $spacing-2;
padding: $spacing-2 $spacing-4;
background: none;
border: none;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
font-size: $font-size-sm;
font-weight: $font-weight-medium;
font-family: $font-family-base;
color: var(--clr-text-secondary);
cursor: pointer;
transition: color $transition-fast, border-color $transition-fast;
&:hover { color: var(--clr-text); }
&--active {
color: var(--clr-primary, #{$color-primary});
border-bottom-color: var(--clr-primary, #{$color-primary});
}
}
&__tab-count {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 18px;
height: 18px;
padding: 0 5px;
background: var(--clr-surface-raised, #{$gray-100});
border-radius: $radius-full;
font-size: 11px;
font-weight: $font-weight-semibold;
color: var(--clr-text-secondary);
.rp__tab--active & {
background: rgba($primary-500, 0.12);
color: $primary-600;
}
}
&__msg {
text-align: center;
padding: $spacing-16 0;
font-size: $font-size-sm;
color: var(--clr-text-secondary);
}
&__list {
display: flex;
flex-direction: column;
gap: $spacing-3;
}
}
// ── Reservation card ─────────────────────────────────────────────────────────
.res-card {
background: var(--clr-surface);
border: 1px solid var(--clr-border);
border-radius: $radius-xl;
overflow: hidden;
transition: box-shadow $transition-fast;
&:hover { box-shadow: $shadow-md; }
&--cancelled {
opacity: 0.7;
}
&--upcoming {
border-left: 3px solid $primary-400;
}
&--highlighted {
box-shadow: 0 0 0 2px $primary-400, $shadow-md;
animation: res-card-pulse 1.2s ease-out;
}
// @keyframes z wieloma klatkami
// które zmieniają box-shadow z 0 0 0 4px rgba($primary-400, 0.5),
// $shadow-md na 0 0 0 2px $primary-400, $shadow-md
// animacja trwa 1.2s i jest ease-out
// jest to animacja pulsowania karty rezerwacji, która jest wyróżniona
@keyframes res-card-pulse {
0% { box-shadow: 0 0 0 4px rgba($primary-400, 0.5), $shadow-md; }
100% { box-shadow: 0 0 0 2px $primary-400, $shadow-md; }
}
// ── Toggle button (collapsed header) ──────────────────────────────────────
&__toggle {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
gap: $spacing-4;
padding: $spacing-4 $spacing-5;
background: none;
border: none;
font-family: $font-family-base;
cursor: pointer;
text-align: left;
color: var(--clr-text);
transition: background $transition-fast;
&:hover { background: var(--clr-surface-raised, #{$gray-50}); }
}
&__summary {
display: flex;
flex-direction: column;
gap: $spacing-1;
flex: 1;
min-width: 0;
}
&__name {
font-size: $font-size-sm;
font-weight: $font-weight-semibold;
color: var(--clr-text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&__meta {
display: flex;
flex-wrap: wrap;
gap: $spacing-3;
}
&__meta-item {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: $font-size-xs;
color: var(--clr-text-secondary);
}
&__right {
display: flex;
align-items: center;
gap: $spacing-3;
flex-shrink: 0;
color: var(--clr-text-secondary);
}
// ── Expanded body ─────────────────────────────────────────────────────────
&__body {
border-top: 1px solid var(--clr-border);
padding: $spacing-5;
display: flex;
flex-direction: column;
gap: $spacing-4;
}
&__dl {
display: grid;
grid-template-columns: 1fr;
gap: 0;
}
&__dl-row {
display: grid;
grid-template-columns: 160px 1fr;
gap: $spacing-3;
padding: $spacing-2 0;
border-bottom: 1px solid var(--clr-border);
&:last-child { border-bottom: none; }
dt {
display: inline-flex;
align-items: center;
gap: $spacing-1;
font-size: $font-size-xs;
font-weight: $font-weight-medium;
color: var(--clr-text-secondary);
}
dd {
font-size: $font-size-xs;
color: var(--clr-text);
word-break: break-all;
}
}
&__mono {
font-family: $font-family-mono;
font-size: 11px;
}
// ── Actions row ───────────────────────────────────────────────────────────
&__actions {
display: flex;
align-items: center;
gap: $spacing-3;
flex-wrap: wrap;
}
&__pdf-btn {
display: inline-flex;
align-items: center;
gap: $spacing-1;
padding: $spacing-2 $spacing-3;
background: transparent;
border: 1px solid var(--clr-border);
border-radius: $radius-full;
font-size: $font-size-xs;
font-weight: $font-weight-medium;
font-family: $font-family-base;
color: var(--clr-text-secondary);
cursor: pointer;
transition: background $transition-fast, color $transition-fast;
&:hover {
background: var(--clr-surface-raised);
color: var(--clr-text);
}
}
// ── Google Calendar link ──────────────────────────────────────────────────
&__cal-btn {
align-self: flex-start;
display: inline-flex;
align-items: center;
gap: $spacing-1;
padding: $spacing-2 $spacing-3;
background: transparent;
border: 1px solid $accent-200;
border-radius: $radius-full;
font-size: $font-size-xs;
font-weight: $font-weight-medium;
color: $accent-700;
text-decoration: none;
transition: background $transition-fast;
&:hover { background: $accent-50; }
}
// ── Re-book trigger ───────────────────────────────────────────────────────
&__rebook-btn {
align-self: flex-start;
display: inline-flex;
align-items: center;
gap: $spacing-1;
padding: $spacing-2 $spacing-3;
background: transparent;
border: 1px solid $accent-200;
border-radius: $radius-full;
font-size: $font-size-xs;
font-weight: $font-weight-medium;
font-family: $font-family-base;
color: $accent-700;
cursor: pointer;
transition: background $transition-fast;
&:hover { background: $accent-50; }
}
// ── Reschedule trigger ────────────────────────────────────────────────────
&__reschedule-btn {
align-self: flex-start;
display: inline-flex;
align-items: center;
gap: $spacing-1;
padding: $spacing-2 $spacing-3;
background: transparent;
border: 1px solid $primary-200;
border-radius: $radius-full;
font-size: $font-size-xs;
font-weight: $font-weight-medium;
font-family: $font-family-base;
color: $primary-600;
cursor: pointer;
transition: background $transition-fast;
&:hover { background: $primary-50; }
}
// ── Cancel trigger ────────────────────────────────────────────────────────
&__cancel-trigger {
align-self: flex-start;
display: inline-flex;
align-items: center;
gap: $spacing-1;
padding: $spacing-2 $spacing-3;
background: transparent;
border: 1px solid #fecaca;
border-radius: $radius-full;
font-size: $font-size-xs;
font-weight: $font-weight-medium;
font-family: $font-family-base;
color: $color-error;
cursor: pointer;
transition: background $transition-fast;
&:hover { background: #fef2f2; }
}
// ── Cancel confirmation ───────────────────────────────────────────────────
&__confirm {
display: flex;
flex-direction: column;
gap: $spacing-3;
padding: $spacing-4;
background: #fffbeb;
border: 1px solid #fde68a;
border-radius: $radius-lg;
}
&__confirm-icon {
color: #d97706;
flex-shrink: 0;
}
&__confirm-text {
font-size: $font-size-sm;
color: #92400e;
margin: 0;
}
&__confirm-btns {
display: flex;
gap: $spacing-3;
}
&__confirm-yes {
padding: $spacing-2 $spacing-4;
background: $color-error;
color: #fff;
border: none;
border-radius: $radius-base;
font-size: $font-size-sm;
font-weight: $font-weight-semibold;
font-family: $font-family-base;
cursor: pointer;
transition: opacity $transition-fast;
&:hover:not(:disabled) { opacity: 0.9; }
&:disabled { opacity: 0.6; cursor: not-allowed; }
}
&__confirm-no {
padding: $spacing-2 $spacing-4;
background: transparent;
border: 1px solid var(--clr-border);
border-radius: $radius-base;
font-size: $font-size-sm;
font-weight: $font-weight-medium;
font-family: $font-family-base;
color: var(--clr-text-secondary);
cursor: pointer;
transition: background $transition-fast;
&:hover { background: var(--clr-surface-raised); }
}
&__reviews {
margin-top: $spacing-4;
padding-top: $spacing-4;
border-top: 1px solid var(--clr-border);
}
}