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).
This commit is contained in:
Krzysztof Cieślik
2026-06-21 06:08:47 +02:00
commit f436d87ca5
99 changed files with 18696 additions and 0 deletions

View File

@@ -0,0 +1,162 @@
@use '../styles/variables' as *;
.analytics {
display: flex;
flex-direction: column;
gap: $spacing-6;
&__toolbar {
display: flex;
justify-content: flex-end;
}
&__export-btn {
display: inline-flex;
align-items: center;
gap: $spacing-2;
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); color: var(--clr-text); }
}
&__cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: $spacing-4;
}
&__charts {
display: grid;
grid-template-columns: 1fr 1fr;
gap: $spacing-4;
@media (max-width: 800px) { grid-template-columns: 1fr; }
}
&__chart-box {
background: var(--clr-surface-raised, #{$gray-50});
border: 1px solid var(--clr-border);
border-radius: $radius-lg;
padding: $spacing-5;
display: flex;
flex-direction: column;
gap: $spacing-4;
}
&__chart-title {
display: flex;
align-items: center;
gap: $spacing-2;
font-size: $font-size-sm;
font-weight: $font-weight-semibold;
color: var(--clr-text);
margin: 0;
}
&__empty {
font-size: $font-size-sm;
color: var(--clr-text-secondary);
font-style: italic;
}
}
// Stat card
.stat {
background: var(--clr-surface);
border: 1px solid var(--clr-border);
border-radius: $radius-lg;
padding: $spacing-4;
display: flex;
align-items: flex-start;
gap: $spacing-3;
&__icon {
width: 40px;
height: 40px;
border-radius: $radius-base;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
background: $gray-100;
color: $gray-600;
}
&--blue &__icon { background: $primary-100; color: $primary-600; }
&--green &__icon { background: $accent-100; color: $accent-600; }
&--yellow &__icon { background: #fef9c3; color: #ca8a04; }
&--red &__icon { background: #fee2e2; color: #dc2626; }
&__body { min-width: 0; }
&__value {
font-size: $font-size-xl;
font-weight: $font-weight-bold;
color: var(--clr-text);
margin: 0;
line-height: 1.2;
}
&__label {
font-size: $font-size-xs;
color: var(--clr-text-secondary);
margin: 2px 0 0;
}
&__sub {
font-size: 11px;
color: var(--clr-text-muted);
margin: 2px 0 0;
}
}
// Bar chart
.bar-chart {
display: flex;
flex-direction: column;
gap: $spacing-2;
&__row {
display: grid;
grid-template-columns: 100px 1fr 36px;
align-items: center;
gap: $spacing-2;
}
&__label {
font-size: 11px;
color: var(--clr-text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&__track {
height: 10px;
background: var(--clr-border);
border-radius: $radius-full;
overflow: hidden;
}
&__fill {
height: 100%;
border-radius: $radius-full;
transition: width 0.5s ease;
}
&__val {
font-size: 11px;
font-weight: $font-weight-semibold;
color: var(--clr-text);
text-align: right;
}
}