Skip to content

Commit e657e91

Browse files
committed
feat(ui): polish Overview 2.0 with progress bar, spacing and CTA layout
- added vacation usage progressbar with percentage indicator - improved spacing, typography and header visual - redesigned quick access area with uniform buttons
1 parent b3c827b commit e657e91

2 files changed

Lines changed: 222 additions & 42 deletions

File tree

tree.txt

Lines changed: 146 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,72 @@
55
│   │   ├── README
66
│   │   ├── script.py.mako
77
│   │   └── versions
8+
│   │   ├── 119d32d1de2f_add_audit_logs_table.py
9+
│   │   ├── 226bebf822b5_create_documenttype_and_documentstatus_.py
10+
│   │   ├── 36df3364963c_switch_documents_employee_id_to_string.py
11+
│   │   ├── 39113ceebce3_add_comment_to_documents.py
12+
│   │   ├── 538e9cd8a84e_sync_schema_after_varchar_employee_id_.py
13+
│   │   ├── 57065dc124a9_init_employees_schema.py
14+
│   │   ├── 5eacbb5b7100_merge_heads_into_one_unified_head.py
15+
│   │   ├── 7e02891eff18_post_uuid_fix.py
16+
│   │   ├── 994efb5b6a6d_convert_employee_id_column_to_string_.py
17+
│   │   ├── 9f515e58cfaf_fix_default_value_for_documents_updated.py
18+
│   │   ├── aa503c802de3_use_unified_enums_for_documents.py
19+
│   │   ├── convert_all_employee_ids_to_string.py
20+
│   │   ├── d01249af0338_merge_orphan_branch_f123456789ab_into_.py
21+
│   │   ├── dff97d9f27d8_merge_documenttype_branches.py
22+
│   │   ├── e81ea845b2af_add_documents_sick_leaves_reminders.py
23+
│   │   └── ee0f1b78c49b_add_avatar_url_to_employees.py
824
│   ├── alembic.ini
925
│   ├── app
26+
│   │   ├── alembic
27+
│   │   ├── alembic.ini
28+
│   │   ├── backend
29+
│   │   ├── core
30+
│   │   │   ├── audit.py
31+
│   │   │   ├── auth.py
32+
│   │   │   └── roles.py
1033
│   │   ├── database.py
34+
│   │   ├── enums.py
1135
│   │   ├── __init__.py
1236
│   │   ├── main.py
1337
│   │   ├── models.py
1438
│   │   ├── __pycache__
39+
│   │   │   ├── database.cpython-313.pyc
40+
│   │   │   ├── main.cpython-313.pyc
41+
│   │   │   ├── models.cpython-313.pyc
42+
│   │   │   └── schemas.cpython-313.pyc
1543
│   │   ├── routers
44+
│   │   │   ├── admin.py
45+
│   │   │   ├── dashboard.py
46+
│   │   │   ├── documents.py
47+
│   │   │   ├── employees.py
48+
│   │   │   ├── health.py
49+
│   │   │   ├── hr.py
50+
│   │   │   ├── __init__.py
51+
│   │   │   ├── meta.py
52+
│   │   │   ├── __pycache__
53+
│   │   │   ├── reminders.py
54+
│   │   │   ├── sick_leaves.py
55+
│   │   │   ├── time_entries.py
56+
│   │   │   └── vacation_requests.py
1657
│   │   ├── schemas.py
58+
│   │   ├── services
59+
│   │   │   └── hr_service.py
1760
│   │   ├── tests
61+
│   │   │   ├── __pycache__
62+
│   │   │   └── test_employee_smoke.py
1863
│   │   ├── uploads
64+
│   │   │   ├── 40ccaeb0-0633-45f5-b1b4-1361d7bcd88e_Rabattprogramm für Mitarbeiter der ManpowerGroup_2023.pdf
65+
│   │   │   ├── 4b2ed865-ff17-4d40-b1ea-733f9e19d7a1_Fact Sheet IT Provider_Eric Bawor (1).pdf
66+
│   │   │   ├── 7abd4163-437e-4770-8f01-838eef50f45c_Fact Sheet IT Provider_Eric Bawor (1).pdf
67+
│   │   │   ├── avatar
68+
│   │   │   ├── cfa4012f-6f28-49aa-aa3a-62dd68301cdf_Rabattprogramm für Mitarbeiter der ManpowerGroup_2023.pdf
69+
│   │   │   └── documents
1970
│   │   └── utils
71+
│   │   ├── helpers.py
72+
│   │   ├── __pycache__
73+
│   │   └── reminders.py
2074
│   ├── backend_start.sh
2175
│   ├── Dockerfile
2276
│   ├── Dockerfile.dev
@@ -30,15 +84,51 @@
3084
│   ├── seed_workmate.py
3185
│   ├── tests
3286
│   │   └── test_health.py
87+
│   ├── uploads
88+
│   │   ├── 40ccaeb0-0633-45f5-b1b4-1361d7bcd88e_Rabattprogramm für Mitarbeiter der ManpowerGroup_2023.pdf
89+
│   │   ├── 4b2ed865-ff17-4d40-b1ea-733f9e19d7a1_Fact Sheet IT Provider_Eric Bawor (1).pdf
90+
│   │   ├── 7abd4163-437e-4770-8f01-838eef50f45c_Fact Sheet IT Provider_Eric Bawor (1).pdf
91+
│   │   ├── avatar
92+
│   │   ├── cfa4012f-6f28-49aa-aa3a-62dd68301cdf_Rabattprogramm für Mitarbeiter der ManpowerGroup_2023.pdf
93+
│   │   └── documents
94+
│   │   └── KIT-0001
3395
│   └── venv
3496
│   ├── bin
97+
│   │   ├── activate
98+
│   │   ├── activate.csh
99+
│   │   ├── activate.fish
100+
│   │   ├── Activate.ps1
101+
│   │   ├── alembic
102+
│   │   ├── dotenv
103+
│   │   ├── email_validator
104+
│   │   ├── fastapi
105+
│   │   ├── httpx
106+
│   │   ├── jose
107+
│   │   ├── mako-render
108+
│   │   ├── normalizer
109+
│   │   ├── pip
110+
│   │   ├── pip3
111+
│   │   ├── pip3.13
112+
│   │   ├── pygmentize
113+
│   │   ├── py.test
114+
│   │   ├── pytest
115+
│   │   ├── python -> /usr/bin/python
116+
│   │   ├── python3 -> python
117+
│   │   ├── python3.13 -> python
118+
│   │   ├── uvicorn
119+
│   │   └── wheel
35120
│   ├── include
121+
│   │   ├── python3.13
122+
│   │   └── site
36123
│   ├── lib
124+
│   │   └── python3.13
37125
│   ├── lib64 -> lib
38126
│   └── pyvenv.cfg
39127
├── clean_ui.sh
128+
├── dev-setup-check.sh
40129
├── docker-compose.prod.yml
41130
├── docker-compose.yml
131+
├── log_backend_alembic.txt
42132
├── Makefile
43133
├── notes-gpt.txt
44134
├── pg_backup_2025-10-09.sql
@@ -58,40 +148,91 @@
58148
├── node_modules
59149
│   ├── autoprefixer -> .pnpm/autoprefixer@10.4.21_postcss@8.5.6/node_modules/autoprefixer
60150
│   ├── axios -> .pnpm/axios@1.12.2/node_modules/axios
61-
│   ├── chart.js -> .pnpm/chart.js@4.5.0/node_modules/chart.js
151+
│   ├── blueimp-md5 -> .pnpm/blueimp-md5@2.19.0/node_modules/blueimp-md5
152+
│   ├── chart.js -> .pnpm/chart.js@4.5.1/node_modules/chart.js
62153
│   ├── @heroicons
154+
│   │   └── vue -> ../.pnpm/@heroicons+vue@2.2.0_vue@3.5.22_typescript@5.8.3_/node_modules/@heroicons/vue
155+
│   ├── keycloak-js -> .pnpm/keycloak-js@26.2.1/node_modules/keycloak-js
156+
│   ├── lucide-vue-next -> .pnpm/lucide-vue-next@0.545.0_vue@3.5.22_typescript@5.8.3_/node_modules/lucide-vue-next
63157
│   ├── postcss -> .pnpm/postcss@8.5.6/node_modules/postcss
64158
│   ├── tailwindcss -> .pnpm/tailwindcss@3.4.18/node_modules/tailwindcss
65159
│   ├── @types
160+
│   │   └── node -> ../.pnpm/@types+node@24.7.2/node_modules/@types/node
66161
│   ├── typescript -> .pnpm/typescript@5.8.3/node_modules/typescript
67-
│   ├── vite -> .pnpm/vite@7.1.9_@types+node@24.7.1_jiti@1.21.7/node_modules/vite
162+
│   ├── vite -> .pnpm/vite@7.1.9_@types+node@24.7.2_jiti@1.21.7/node_modules/vite
68163
│   ├── @vitejs
164+
│   │   └── plugin-vue -> ../.pnpm/@vitejs+plugin-vue@6.0.1_vite@7.1.9_@types+node@24.7.2_jiti@1.21.7__vue@3.5.22_typescript@5.8.3_/node_modules/@vitejs/plugin-vue
69165
│   ├── @vue
166+
│   │   └── tsconfig -> ../.pnpm/@vue+tsconfig@0.7.0_typescript@5.8.3_vue@3.5.22_typescript@5.8.3_/node_modules/@vue/tsconfig
70167
│   ├── vue -> .pnpm/vue@3.5.22_typescript@5.8.3/node_modules/vue
71-
│   ├── vue-chartjs -> .pnpm/vue-chartjs@5.3.2_chart.js@4.5.0_vue@3.5.22_typescript@5.8.3_/node_modules/vue-chartjs
168+
│   ├── vue3-apexcharts -> .pnpm/vue3-apexcharts@1.9.0_apexcharts@5.3.5_vue@3.5.22_typescript@5.8.3_/node_modules/vue3-apexcharts
169+
│   ├── vue-chartjs -> .pnpm/vue-chartjs@5.3.2_chart.js@4.5.1_vue@3.5.22_typescript@5.8.3_/node_modules/vue-chartjs
72170
│   ├── vue-router -> .pnpm/vue-router@4.5.1_vue@3.5.22_typescript@5.8.3_/node_modules/vue-router
73171
│   └── vue-tsc -> .pnpm/vue-tsc@3.1.1_typescript@5.8.3/node_modules/vue-tsc
74172
├── package.json
75173
├── pnpm-lock.yaml
76174
├── postcss.config.js
77175
├── public
78-
│   └── vite.svg
176+
│   ├── healthz
177+
│   ├── silent-check-sso.html
178+
│   ├── vite.svg
179+
│   ├── workmate_dark_transparent.png
180+
│   ├── workmate_favicon.ico
181+
│   └── workmate_white_transparent.png
79182
├── README.md
80183
├── src
81184
│   ├── App.vue
82185
│   ├── assets
186+
│   │   └── vue.svg
83187
│   ├── components
188+
│   │   ├── AbsenceCalendar.vue
189+
│   │   ├── admin
190+
│   │   ├── charts
191+
│   │   ├── DeptPopover.vue
192+
│   │   ├── documents
193+
│   │   ├── employee
194+
│   │   ├── EmployeeEditForm.vue
195+
│   │   ├── HRDashboard.vue
196+
│   │   ├── HRDepartmentEmployees.vue
197+
│   │   ├── KpiCard.vue
198+
│   │   ├── layout
199+
│   │   ├── Section.vue
200+
│   │   ├── system
201+
│   │   ├── TopEmployees.vue
202+
│   │   └── UserBar.vue
203+
│   ├── composables
204+
│   │   ├── useAuth.ts
205+
│   │   ├── useHealth.ts
206+
│   │   └── useTheme.ts
207+
│   ├── enums
208+
│   │   └── documentStatus.ts
84209
│   ├── https-guard.dev.ts
85210
│   ├── index.css
86211
│   ├── lib
212+
│   │   ├── api.ts
213+
│   │   ├── avatar.ts
214+
│   │   ├── iconMap.ts
215+
│   │   ├── keycloak.ts
216+
│   │   └── types.ts
87217
│   ├── main.ts
88218
│   ├── router
219+
│   │   └── index.ts
220+
│   ├── types
221+
│   │   └── blueimp-md5.d.ts
89222
│   ├── views
223+
│   │   ├── admin
224+
│   │   ├── Documents.vue
225+
│   │   ├── EmployeeDetail.vue
226+
│   │   ├── Employees.vue
227+
│   │   ├── Employee.vue
228+
│   │   ├── hr
229+
│   │   ├── Overview.vue
230+
│   │   └── SetupProfile.vue
90231
│   └── vite-env.d.ts
91232
├── tailwind.config.js
92233
├── tsconfig.app.json
93234
├── tsconfig.json
94235
├── tsconfig.node.json
95236
└── vite.config.ts
96237

97-
43 directories, 52 files
238+
78 directories, 158 files

ui/src/views/Overview.vue

Lines changed: 76 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ onMounted(async () => {
2626
}
2727
})
2828
29+
// ----------------------------
30+
// 📊 Berechnungen
31+
// ----------------------------
32+
const vacationPercent = computed(() => {
33+
const used =
34+
(data.value?.vacations?.total ?? 0) -
35+
(data.value?.vacations?.remaining ?? 0)
36+
const total = data.value?.vacations?.total ?? 1
37+
return Math.round((used / total) * 100)
38+
})
39+
2940
// ----------------------------
3041
// 🔗 Navigation Shortcuts
3142
// ----------------------------
@@ -55,17 +66,26 @@ function goToProfile() {
5566

5667
<template v-else>
5768
<!-- 🧩 Begrüßung -->
58-
<header class="space-y-1 mb-8">
59-
<h1 class="text-2xl font-semibold text-white">
69+
<header
70+
class="space-y-1 mb-10 p-6 rounded-xl bg-white/5 backdrop-blur-sm border border-white/10 shadow-lg"
71+
>
72+
<h1 class="text-2xl font-semibold text-white tracking-tight">
6073
Willkommen zurück,
61-
<span class="text-[var(--color-accent)]">{{ dbUser?.name || dbUser?.preferred_username|| "Benutzer" }}</span> 👋
74+
<span class="text-[var(--color-accent)] font-bold">
75+
{{ dbUser?.name || dbUser?.preferred_username || "Benutzer" }}
76+
</span>
77+
👋
6278
</h1>
63-
<p class="text-white/60">Abteilung: {{ dbUser?.department || "–" }}</p>
79+
<p class="text-white/60">
80+
Abteilung: {{ dbUser?.department || "–" }}
81+
</p>
6482
</header>
6583

6684
<!-- 📊 KPI-Cards -->
6785
<section>
68-
<div class="grid gap-6 sm:grid-cols-2 xl:grid-cols-4 mt-6">
86+
<div
87+
class="grid gap-8 mt-10 sm:grid-cols-2 xl:grid-cols-4 grid-cols-[repeat(auto-fit,minmax(260px,1fr))]"
88+
>
6989
<KpiCard
7090
title="Offene Reminders"
7191
:value="data?.reminders?.pending_total ?? 0"
@@ -86,7 +106,20 @@ function goToProfile() {
86106
hint="Zu deinen Urlaubsanträgen"
87107
icon="vacation"
88108
@click="goToProfileTab('vacation')"
89-
/>
109+
>
110+
<!-- 🌿 Vacation Progress -->
111+
<template #footer>
112+
<div class="mt-3 h-2 w-full bg-white/10 rounded-full overflow-hidden">
113+
<div
114+
class="h-full bg-gradient-to-r from-emerald-400 to-cyan-500 transition-all duration-500"
115+
:style="{ width: vacationPercent + '%' }"
116+
></div>
117+
</div>
118+
<p class="mt-1 text-xs text-white/60 text-right">
119+
{{ vacationPercent }} % genutzt
120+
</p>
121+
</template>
122+
</KpiCard>
90123
<KpiCard
91124
title="Krankmeldungen"
92125
:value="data?.sick_leaves?.active ?? 0"
@@ -98,54 +131,60 @@ function goToProfile() {
98131
</section>
99132

100133
<!-- ⚡ Schnellzugriff -->
101-
<section class="mt-12">
102-
<h2 class="text-lg font-semibold mb-4 text-white flex items-center gap-2">
134+
<section class="mt-14">
135+
<h2
136+
class="text-lg font-semibold mb-5 text-white flex items-center gap-2 tracking-tight"
137+
>
103138
<span class="w-2 h-2 bg-[var(--color-accent)] rounded-full"></span>
104139
Schnellzugriff
105140
</h2>
106-
<button
107-
class="quick-button"
108-
@click="goToProfile"
141+
142+
<div
143+
class="grid sm:grid-cols-2 lg:grid-cols-3 gap-5 text-center"
109144
>
110-
Mein Profil öffnen
111-
</button>
145+
<button
146+
class="quick-button"
147+
@click="goToProfile"
148+
>
149+
Mein Profil öffnen
150+
</button>
151+
<button
152+
class="quick-button"
153+
@click="goToProfileTab('documents')"
154+
>
155+
Meine Dokumente
156+
</button>
157+
<button
158+
class="quick-button"
159+
@click="goToProfileTab('reminders')"
160+
>
161+
Meine Reminders
162+
</button>
163+
</div>
112164
</section>
113165
</template>
114166
</div>
115167
</template>
116168

117169
<style scoped>
118170
.overview-page {
119-
@apply min-h-screen px-8 pb-16;
171+
@apply min-h-screen px-8 pb-20;
120172
}
121173
122174
/* ===== Ladezustände ===== */
123-
.loading, .error {
175+
.loading,
176+
.error {
124177
@apply text-white/70 text-center mt-10;
125178
}
126-
.error { @apply text-rose-400; }
127-
128-
/* ===== Schnellzugriff Button ===== */
129-
.quick-button {
130-
@apply bg-[var(--color-accent)] text-black font-semibold px-6 py-3 rounded-lg
131-
hover:bg-[var(--color-accent-hover)] transition-all duration-200
132-
shadow-[0_0_20px_rgba(255,145,0,0.25)] hover:shadow-[0_0_30px_rgba(255,145,0,0.4)]
133-
active:scale-[0.98];
179+
.error {
180+
@apply text-rose-400;
134181
}
135182
136-
/* ===== KPI Grid allgemeine Layoutverbesserung ===== */
137-
.grid > * {
138-
background: var(--color-surface);
139-
border: 1px solid var(--color-border);
140-
border-radius: 1rem;
141-
padding: 1.5rem;
142-
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.4);
143-
transition: all 0.25s ease;
144-
}
145-
.grid > *:hover {
146-
transform: translateY(-3px);
147-
box-shadow:
148-
0 6px 24px rgba(0, 0, 0, 0.5),
149-
0 0 25px rgba(255, 145, 0, 0.15);
183+
/* ===== Schnellzugriff Buttons ===== */
184+
.quick-button {
185+
@apply bg-white/5 text-white font-medium px-6 py-3 rounded-lg border border-white/10
186+
hover:bg-[var(--color-accent)] hover:text-black transition-all duration-200
187+
shadow-[0_0_15px_rgba(255,145,0,0.1)] hover:shadow-[0_0_25px_rgba(255,145,0,0.3)]
188+
backdrop-blur-sm;
150189
}
151190
</style>

0 commit comments

Comments
 (0)