Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 

736 righe
17 KiB

  1. @use '../atoms/variables' as *;
  2. @use '../atoms/mixins' as *;
  3. // ─── Page ─────────────────────────────────────────────────────────────────────
  4. .report-page {
  5. @include page-shell;
  6. }
  7. // ─── Header ──────────────────────────────────────────────────────────────────
  8. .report-header {
  9. @include section-header;
  10. padding: $space-4 $space-6;
  11. @include tablet {
  12. flex-direction: column;
  13. align-items: stretch;
  14. gap: $space-3;
  15. }
  16. }
  17. .report-header__title {
  18. font-size: $font-size-xl;
  19. font-weight: $font-weight-bold;
  20. color: var(--header-text);
  21. }
  22. .report-header__right {
  23. display: flex;
  24. align-items: center;
  25. gap: $space-4;
  26. @include tablet {
  27. flex-wrap: wrap;
  28. }
  29. }
  30. // ─── Account-Name Anzeige ────────────────────────────────────────────────────
  31. .report-account-name {
  32. display: inline-flex;
  33. align-items: center;
  34. gap: $space-2;
  35. padding: $space-2 $space-4;
  36. font-size: $font-size-sm;
  37. font-weight: $font-weight-medium;
  38. color: var(--header-text);
  39. background: var(--header-overlay);
  40. border: 1px solid var(--header-overlay);
  41. border-radius: $radius-pill;
  42. backdrop-filter: blur(6px);
  43. -webkit-backdrop-filter: blur(6px);
  44. white-space: nowrap;
  45. &__icon {
  46. width: 16px;
  47. height: 16px;
  48. flex-shrink: 0;
  49. }
  50. }
  51. // ─── Disabled Tab ────────────────────────────────────────────────────────────
  52. .account-tab--disabled {
  53. opacity: 0.45;
  54. pointer-events: none;
  55. cursor: default;
  56. }
  57. // ─── Content ─────────────────────────────────────────────────────────────────
  58. .report-content {
  59. flex: 1;
  60. max-width: 1200px;
  61. width: 100%;
  62. margin: $space-6 auto;
  63. padding: 0 $space-6;
  64. @include tablet {
  65. padding: 0 $space-4;
  66. }
  67. }
  68. // ─── Karte ───────────────────────────────────────────────────────────────────
  69. .report-card {
  70. @include card;
  71. overflow: hidden;
  72. @include tablet { overflow-x: auto; }
  73. }
  74. // ─── Toolbar ─────────────────────────────────────────────────────────────────
  75. .report-toolbar {
  76. display: flex;
  77. align-items: center;
  78. justify-content: space-between;
  79. padding: $space-3 $space-5;
  80. border-bottom: 1px solid $color-border;
  81. @include tablet {
  82. flex-wrap: wrap;
  83. gap: $space-3;
  84. }
  85. }
  86. .report-toolbar__left {
  87. display: flex;
  88. align-items: center;
  89. gap: $space-6;
  90. }
  91. .report-toolbar__right {
  92. display: flex;
  93. align-items: center;
  94. gap: $space-2;
  95. }
  96. .report-toolbar__export {
  97. @include icon-btn(30px, $radius-sm);
  98. color: $color-text-light;
  99. svg { width: 18px; height: 18px; }
  100. &:hover {
  101. color: var(--color-primary);
  102. background: rgba(var(--color-primary-rgb), 0.08);
  103. }
  104. }
  105. .report-toolbar__separator {
  106. width: 1px;
  107. height: 18px;
  108. background: $color-border;
  109. margin: 0 $space-1;
  110. }
  111. .report-toolbar__action {
  112. display: inline-flex;
  113. align-items: center;
  114. gap: $space-2;
  115. font-size: $font-size-sm;
  116. font-weight: $font-weight-medium;
  117. color: var(--color-primary);
  118. cursor: pointer;
  119. text-decoration: none;
  120. svg {
  121. width: $icon-svg-size;
  122. height: $icon-svg-size;
  123. flex-shrink: 0;
  124. }
  125. &--disabled {
  126. color: $color-text-muted;
  127. pointer-events: none;
  128. cursor: default;
  129. }
  130. }
  131. // ─── Tabelle ─────────────────────────────────────────────────────────────────
  132. .report-table {
  133. width: 100%;
  134. @include tablet { min-width: 900px; }
  135. }
  136. .report-table__head,
  137. .report-table__row {
  138. display: grid;
  139. grid-template-columns:
  140. 110px // Datum
  141. 140px // Kunde
  142. 130px // Projekt
  143. 120px // Leistung
  144. 140px // Benutzer
  145. 1fr // Bemerkung
  146. 80px // Stunden
  147. 100px // Umsatz
  148. 88px; // Aktionen
  149. align-items: center;
  150. border-bottom: 1px solid $color-border;
  151. padding: 0 $space-5;
  152. }
  153. .report-table__head {
  154. padding-top: $space-2;
  155. padding-bottom: $space-2;
  156. .report-table__cell {
  157. font-size: $font-size-xs;
  158. font-weight: $font-weight-bold;
  159. color: $color-text-base;
  160. text-transform: uppercase;
  161. letter-spacing: 0.03em;
  162. line-height: 1.3;
  163. }
  164. }
  165. .report-table__row {
  166. padding-top: $space-3;
  167. padding-bottom: $space-3;
  168. transition: background $transition-fast;
  169. &:hover {
  170. background: rgba(var(--color-primary-rgb), 0.05);
  171. .report-action-btn { opacity: 1; }
  172. }
  173. &--invoiced .report-table__cell {
  174. &--date, &--client, &--project, &--service,
  175. &--user, &--note, &--duration, &--revenue {
  176. color: $color-text-light;
  177. }
  178. }
  179. &--editing {
  180. background: rgba(var(--color-primary-rgb), 0.05);
  181. .report-table__cell--actions { visibility: hidden; }
  182. }
  183. &:last-child { border-bottom: none; }
  184. }
  185. .report-table__cell {
  186. font-size: $font-size-base;
  187. color: $color-text-base;
  188. padding-right: $space-3;
  189. line-height: 1.4;
  190. min-width: 0;
  191. &--duration,
  192. &--revenue {
  193. text-align: right;
  194. padding-right: $space-4;
  195. white-space: nowrap;
  196. font-variant-numeric: tabular-nums;
  197. }
  198. &--actions {
  199. display: flex;
  200. align-items: center;
  201. justify-content: flex-end;
  202. gap: $space-1;
  203. padding-right: 0;
  204. }
  205. &--note {
  206. color: $color-text-muted;
  207. font-size: $font-size-sm;
  208. @include text-truncate;
  209. }
  210. }
  211. .report-table__cell--sortable {
  212. cursor: pointer;
  213. user-select: none;
  214. &:hover .report-table__cell-label { color: var(--color-primary); }
  215. }
  216. .report-table__cell--sorted .report-table__cell-label {
  217. color: var(--color-primary);
  218. }
  219. .report-table__cell-label {
  220. transition: color $transition-fast;
  221. }
  222. .report-table__sort-icon {
  223. margin-left: 2px;
  224. font-size: $font-size-xs;
  225. }
  226. .report-table__summary {
  227. display: block;
  228. font-size: $font-size-xs;
  229. font-weight: $font-weight-regular;
  230. color: $color-text-muted;
  231. margin-top: 1px;
  232. }
  233. .report-table__empty {
  234. padding: $space-10 $space-5;
  235. text-align: center;
  236. color: $color-text-muted;
  237. font-size: $font-size-sm;
  238. }
  239. // ─── Aktions-Buttons (Edit / Delete) ─────────────────────────────────────────
  240. .report-action-btn {
  241. @include icon-btn(26px, $radius-sm);
  242. opacity: 0;
  243. color: $color-text-light;
  244. svg { width: $icon-svg-size; height: $icon-svg-size; }
  245. @include tablet { opacity: 1; }
  246. &:hover {
  247. color: $color-text-muted;
  248. background: rgba($color-text-dark, 0.06);
  249. }
  250. &--delete:hover {
  251. color: $color-error;
  252. background: rgba($color-error, 0.08);
  253. }
  254. }
  255. // ─── Schloss-Button ──────────────────────────────────────────────────────────
  256. .report-lock {
  257. @include icon-btn(24px, $radius-sm);
  258. color: $color-text-light;
  259. svg { width: $icon-svg-size; height: $icon-svg-size; }
  260. &:hover {
  261. color: $color-text-muted;
  262. background: rgba($color-text-dark, 0.06);
  263. }
  264. &--invoiced {
  265. color: $color-text-dark;
  266. &:hover {
  267. color: $color-text-dark;
  268. background: rgba($color-text-dark, 0.06);
  269. }
  270. }
  271. }
  272. // ─── Inline-Edit-Formular ────────────────────────────────────────────────────
  273. .report-row__edit {
  274. grid-column: 1 / -1;
  275. padding: $space-4 0;
  276. background: rgba(var(--color-primary-rgb), 0.04);
  277. border-top: 1px solid $color-border;
  278. }
  279. .report-row__edit-grid {
  280. display: grid;
  281. grid-template-columns: 140px 1fr;
  282. gap: $space-3 $space-5;
  283. align-items: center;
  284. max-width: 680px;
  285. @include tablet {
  286. grid-template-columns: 1fr;
  287. gap: $space-3;
  288. }
  289. }
  290. .report-row__edit-label {
  291. @include form-label;
  292. @include tablet {
  293. text-align: left;
  294. padding-right: 0;
  295. }
  296. }
  297. .report-row__edit-field {
  298. display: flex;
  299. align-items: center;
  300. gap: $space-2;
  301. &--selects {
  302. gap: $space-3;
  303. .select {
  304. flex: 1;
  305. min-width: 160px;
  306. }
  307. @include tablet {
  308. flex-direction: column;
  309. .select {
  310. min-width: 0;
  311. width: 100%;
  312. }
  313. }
  314. }
  315. .textarea {
  316. width: 100%;
  317. }
  318. }
  319. .report-row__edit-actions {
  320. grid-column: 2;
  321. display: flex;
  322. gap: $space-3;
  323. padding-top: $space-2;
  324. @include tablet {
  325. grid-column: 1;
  326. .btn { flex: 1; }
  327. }
  328. }
  329. // ─── Pagination-Footer ────────────────────────────────────────────────────────
  330. .report-pagination {
  331. display: grid;
  332. grid-template-columns: 1fr 80px 100px 88px;
  333. align-items: center;
  334. padding: $space-3 $space-5;
  335. border-top: 1px solid $color-border;
  336. font-size: $font-size-sm;
  337. color: $color-text-muted;
  338. }
  339. .report-pagination__limits {
  340. display: flex;
  341. align-items: center;
  342. gap: $space-2;
  343. a {
  344. color: var(--color-primary);
  345. text-decoration: underline;
  346. cursor: pointer;
  347. &:hover { color: var(--color-primary-dark); }
  348. }
  349. strong {
  350. color: $color-text-dark;
  351. font-weight: $font-weight-bold;
  352. }
  353. }
  354. .report-pagination__duration,
  355. .report-pagination__revenue {
  356. text-align: right;
  357. padding-right: $space-4;
  358. font-weight: $font-weight-medium;
  359. color: $color-text-muted;
  360. font-variant-numeric: tabular-nums;
  361. white-space: nowrap;
  362. }
  363. .report-pagination__lock-spacer {
  364. // Platzhalter – hält Spalten-Ausrichtung mit der Tabelle
  365. }
  366. // ─── Toolbar-Button (klickbar) ────────────────────────────────────────────────
  367. button.report-toolbar__action {
  368. background: none;
  369. border: none;
  370. cursor: pointer;
  371. font-family: $font-family-base;
  372. padding: $space-1 $space-3;
  373. margin: (-$space-1) (-$space-3);
  374. border-radius: $radius-pill;
  375. transition: background $transition-fast, color $transition-fast;
  376. &--active {
  377. background: $color-text-dark;
  378. color: $color-white;
  379. svg path,
  380. svg circle {
  381. stroke: $color-white;
  382. }
  383. }
  384. }
  385. // ─── Filter-Panel ─────────────────────────────────────────────────────────────
  386. .report-filter {
  387. background: $color-card;
  388. border-bottom: 1px solid $color-border;
  389. padding: $space-5 $space-5 0;
  390. }
  391. .report-filter__body {
  392. display: flex;
  393. gap: $space-10;
  394. @include tablet {
  395. flex-direction: column;
  396. gap: $space-6;
  397. }
  398. }
  399. .report-filter__col {
  400. flex: 1;
  401. min-width: 0;
  402. max-width: 66%;
  403. @include tablet { max-width: 100%; }
  404. }
  405. .report-filter__heading {
  406. font-size: $font-size-xs;
  407. font-weight: $font-weight-bold;
  408. color: $color-text-muted;
  409. text-transform: uppercase;
  410. letter-spacing: 0.06em;
  411. margin-bottom: $space-3;
  412. }
  413. // ─── Filter-Row ───────────────────────────────────────────────────────────────
  414. .filter-row {
  415. display: grid;
  416. grid-template-columns: 160px 1fr;
  417. align-items: flex-start;
  418. gap: $space-3;
  419. padding: $space-2 0;
  420. border-bottom: 1px solid rgba($color-border, 0.6);
  421. &:last-child { border-bottom: none; }
  422. @include mobile {
  423. grid-template-columns: 1fr;
  424. }
  425. &--inactive {
  426. .filter-select,
  427. .filter-note-input,
  428. .filter-period-select,
  429. .filter-radio {
  430. opacity: 0.5;
  431. }
  432. .filter-select,
  433. .filter-note-input,
  434. .filter-period-select {
  435. color: $color-text-muted;
  436. }
  437. .filter-row__add,
  438. .filter-neg {
  439. opacity: 0.4;
  440. }
  441. .filter-neg {
  442. pointer-events: none;
  443. }
  444. }
  445. }
  446. .filter-row__label {
  447. display: flex;
  448. align-items: center;
  449. gap: $space-2;
  450. cursor: pointer;
  451. font-size: $font-size-sm;
  452. color: $color-text-base;
  453. padding-top: 7px;
  454. user-select: none;
  455. }
  456. .filter-row__checkbox {
  457. width: 14px;
  458. height: 14px;
  459. cursor: pointer;
  460. flex-shrink: 0;
  461. accent-color: var(--color-primary);
  462. }
  463. // ─── Body: Controls + Meta nebeneinander ────────────────────────────────────
  464. .filter-row__body {
  465. display: flex;
  466. align-items: flex-start;
  467. gap: $space-3;
  468. }
  469. .filter-row__controls {
  470. display: flex;
  471. flex-direction: column;
  472. gap: $space-2;
  473. min-width: 0;
  474. flex: 1;
  475. }
  476. .filter-row__control-group {
  477. display: flex;
  478. align-items: center;
  479. gap: $space-2;
  480. .filter-select,
  481. .filter-note-input {
  482. width: 300px;
  483. max-width: 100%;
  484. @include tablet { width: 100%; }
  485. }
  486. &--period {
  487. flex-direction: column;
  488. align-items: flex-start;
  489. gap: $space-2;
  490. }
  491. &--radio {
  492. padding-top: 7px;
  493. gap: $space-4;
  494. }
  495. }
  496. // ─── Meta: Plus-Button + Negativfilter ──────────────────────────────────────
  497. .filter-row__meta {
  498. display: flex;
  499. align-items: center;
  500. gap: $space-3;
  501. padding-top: 7px;
  502. flex-shrink: 0;
  503. white-space: nowrap;
  504. &--no-add {
  505. padding-left: calc(22px + #{$space-3});
  506. }
  507. }
  508. // ─── Plus- und Minus-Button ───────────────────────────────────────────────────
  509. .filter-row__add {
  510. @include icon-btn(22px, $radius-sm);
  511. border: 1px solid $color-input-border;
  512. background: $color-white;
  513. font-size: $font-size-md;
  514. line-height: 1;
  515. color: $color-text-muted;
  516. &:hover {
  517. border-color: var(--color-primary);
  518. color: var(--color-primary);
  519. }
  520. }
  521. .filter-row__remove {
  522. @include icon-btn(20px, $radius-sm);
  523. font-size: $font-size-md;
  524. line-height: 1;
  525. color: $color-text-light;
  526. &:hover {
  527. color: $color-error;
  528. background: rgba($color-error, 0.08);
  529. }
  530. }
  531. // ─── Zeitraum: Custom-Datumsfelder ───────────────────────────────────────────
  532. .filter-custom-dates {
  533. display: flex;
  534. flex-direction: column;
  535. gap: $space-2;
  536. margin-top: $space-2;
  537. }
  538. .filter-date-group {
  539. display: flex;
  540. align-items: center;
  541. gap: $space-2;
  542. }
  543. .filter-date-label {
  544. font-size: $font-size-sm;
  545. color: $color-text-muted;
  546. width: 26px;
  547. flex-shrink: 0;
  548. }
  549. .filter-date-select {
  550. width: auto;
  551. display: inline-block;
  552. &--sm {
  553. padding-right: $space-6;
  554. min-width: 60px;
  555. }
  556. &--month {
  557. padding-right: $space-6;
  558. min-width: 100px;
  559. }
  560. }
  561. // ─── Radio-Filter (Abgeschlossen?) ────────────────────────────────────────────
  562. .filter-radio {
  563. display: inline-flex;
  564. align-items: center;
  565. gap: $space-1;
  566. font-size: $font-size-sm;
  567. color: $color-text-base;
  568. cursor: pointer;
  569. user-select: none;
  570. accent-color: var(--color-primary);
  571. }
  572. // ─── Filter-Footer ────────────────────────────────────────────────────────────
  573. .report-filter__footer {
  574. display: flex;
  575. align-items: center;
  576. gap: $space-4;
  577. padding: $space-4 0;
  578. }
  579. .filter-footer__link {
  580. background: none;
  581. border: none;
  582. padding: 0;
  583. cursor: pointer;
  584. font-family: $font-family-base;
  585. font-size: $font-size-sm;
  586. color: $color-text-muted;
  587. text-decoration: underline;
  588. text-underline-offset: 2px;
  589. transition: color $transition-fast;
  590. &:hover { color: $color-text-base; }
  591. }
  592. // ─── Negativfilter-Checkbox ───────────────────────────────────────────────────
  593. .filter-neg {
  594. display: inline-flex;
  595. align-items: center;
  596. gap: $space-1;
  597. font-size: $font-size-sm;
  598. color: $color-text-muted;
  599. cursor: pointer;
  600. user-select: none;
  601. white-space: nowrap;
  602. input[type="checkbox"] {
  603. width: 13px;
  604. height: 13px;
  605. cursor: pointer;
  606. accent-color: $color-warning;
  607. flex-shrink: 0;
  608. }
  609. &:has(input:checked) {
  610. color: $color-warning;
  611. font-weight: $font-weight-medium;
  612. }
  613. }