Compare commits

...

99 Commits

Author SHA1 Message Date
Docker Config Backup
2b26dd17f8 Complete CA and CB column styling with borders and backgrounds
- Add left borders to CB column (CB2-CB22 and CB24-CB27, excluding CB23)
- Apply matching background colors to CA column (#FCD5B4 for rows 7-9, #D9D9D9 alternating)
- Add dotted top borders to CA column for employee rows (CA8-CA27 excluding CA23/24)
- Ensure solid top borders on CA23 and CA24 for section separators
- Add top borders to CA28 for complete section structure
- Maintain visual consistency between main table and additional columns

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-08 12:34:19 +02:00
Docker Config Backup
cb1901af3f Add unformatted CB column and complete CA border structure
- Add completely unformatted CB column at rightmost position
- Update all styling loops to exclude CB column from formatting
- Fix day names row borders to exclude CB from styling
- Add CB6 formatting removal to ensure clean appearance
- Complete CA column border structure with top borders on CA24 and CA28
- Maintain clean separation between formatted (CA) and unformatted (CB) columns

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-06 07:53:52 +02:00
Docker Config Backup
38d88127ba Enhance spreadsheet styling with comprehensive border system and formatting
- Add contextmenu fix to prevent TypeError
- Implement complete border system with top/left borders for all header rows
- Add dotted borders for employee rows (rows 8+)
- Create alternating row backgrounds (#D9D9D9) for better readability
- Add section separators at rows 23-24 and 28
- Implement background colors for rows 7-9 (#FCD5B4)
- Add day column separators (B,D,F,H etc.) from row 6 to end
- Create merged cell CA2:CA6 with proper borders
- Fix first row rotation for all cells including weekend merged cells
- Remove borders at section breaks for clean visual separation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-05 07:51:01 +02:00
Docker Config Backup
158c9f5375 Final auto-save before shutdown
Auto-saved at 2025-07-31 13:42:49

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 13:42:49 +02:00
Docker Config Backup
ec8f51ebb1 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 13:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 13:24:37 +02:00
Docker Config Backup
ec1168308c Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 12:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 12:54:37 +02:00
Docker Config Backup
5a3c628583 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 12:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 12:24:37 +02:00
Docker Config Backup
a84f5d755e Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 11:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 11:54:37 +02:00
Docker Config Backup
bef574b0b5 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 11:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 11:24:37 +02:00
Docker Config Backup
c4e2f153ff Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 10:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 10:54:37 +02:00
Docker Config Backup
b562297e58 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 10:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 10:24:37 +02:00
Docker Config Backup
b182016b90 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 09:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 09:54:37 +02:00
Docker Config Backup
15137a50bf Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 09:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 09:24:37 +02:00
Docker Config Backup
72bc6ff360 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 08:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 08:54:37 +02:00
Docker Config Backup
2721e2a037 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 08:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 08:24:37 +02:00
Docker Config Backup
68c52ae8b6 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 07:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 07:54:37 +02:00
Docker Config Backup
6add9399f8 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 07:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 07:24:37 +02:00
Docker Config Backup
c43f2ca1af Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 06:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 06:54:37 +02:00
Docker Config Backup
6dd08cd528 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 06:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 06:24:37 +02:00
Docker Config Backup
4255f872ae Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 05:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 05:54:37 +02:00
Docker Config Backup
c6f63d0641 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 05:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 05:24:37 +02:00
Docker Config Backup
896ffdc2a7 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 04:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 04:54:37 +02:00
Docker Config Backup
5bff9b7d78 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 04:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 04:24:37 +02:00
Docker Config Backup
9faa573186 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 03:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 03:54:37 +02:00
Docker Config Backup
560c3de82e Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 03:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 03:24:37 +02:00
Docker Config Backup
396a644447 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 02:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 02:54:37 +02:00
Docker Config Backup
05c3976f8d Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 02:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 02:24:37 +02:00
Docker Config Backup
d385a874f3 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 01:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 01:54:37 +02:00
Docker Config Backup
09d20b0986 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 01:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 01:24:37 +02:00
Docker Config Backup
0238f924e1 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 00:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 00:54:37 +02:00
Docker Config Backup
f33b53eb3e Save before creating restore point: Periodic backup
Auto-saved at 2025-07-31 00:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-31 00:24:37 +02:00
Docker Config Backup
459199888c Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 23:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 23:54:37 +02:00
Docker Config Backup
b50be44798 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 23:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 23:24:37 +02:00
Docker Config Backup
8991f7628f Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 22:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 22:54:37 +02:00
Docker Config Backup
3d7b9817a9 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 22:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 22:24:37 +02:00
Docker Config Backup
924e77302b Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 21:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 21:54:37 +02:00
Docker Config Backup
778d52dacb Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 21:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 21:24:37 +02:00
Docker Config Backup
1770dd014c Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 20:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 20:54:37 +02:00
Docker Config Backup
31c05ee3c3 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 20:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 20:24:37 +02:00
Docker Config Backup
09f2ab2d57 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 19:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 19:54:37 +02:00
Docker Config Backup
ea26dd1e90 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 19:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 19:24:37 +02:00
Docker Config Backup
8389bd68df Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 18:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 18:54:37 +02:00
Docker Config Backup
f38a757b65 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 18:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 18:24:37 +02:00
Docker Config Backup
e0fda2819c Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 17:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 17:54:37 +02:00
Docker Config Backup
ec73785754 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 17:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 17:24:37 +02:00
Docker Config Backup
5915c1fd16 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 16:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 16:54:37 +02:00
Docker Config Backup
1d121f5a32 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 16:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 16:24:37 +02:00
Docker Config Backup
22da72ce18 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 15:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 15:54:37 +02:00
Docker Config Backup
9e1458ce62 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 15:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 15:24:37 +02:00
Docker Config Backup
39d61e916c Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 14:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 14:54:37 +02:00
Docker Config Backup
5071f574e7 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 14:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 14:24:37 +02:00
Docker Config Backup
24e3341802 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 13:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 13:54:37 +02:00
Docker Config Backup
2110de81c4 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 13:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 13:24:37 +02:00
Docker Config Backup
11aac2b8c2 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 12:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 12:54:37 +02:00
Docker Config Backup
d390613a1c Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 12:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 12:24:37 +02:00
Docker Config Backup
8aca9d2425 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 11:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 11:54:37 +02:00
Docker Config Backup
809482259f Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 11:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 11:24:37 +02:00
Docker Config Backup
cec8e47eea Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 10:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 10:54:37 +02:00
Docker Config Backup
4258c9e553 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 10:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 10:24:37 +02:00
Docker Config Backup
d139072aed Auto-save: Updated app/layout.tsx
Auto-saved at 2025-07-30 10:08:28

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 10:08:28 +02:00
Docker Config Backup
da6bd84a45 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 09:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 09:54:37 +02:00
Docker Config Backup
b22b12918e Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 09:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 09:24:37 +02:00
Docker Config Backup
318fef77aa Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 08:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 08:54:37 +02:00
Docker Config Backup
5e332aac05 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 08:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 08:24:37 +02:00
Docker Config Backup
4322dfbe54 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 07:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 07:54:37 +02:00
Docker Config Backup
1cfbb0b72f Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 07:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 07:24:37 +02:00
Docker Config Backup
1d844ad6f9 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 06:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 06:54:37 +02:00
Docker Config Backup
adf8eb3021 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 06:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 06:24:37 +02:00
Docker Config Backup
590fafb054 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 05:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 05:54:37 +02:00
Docker Config Backup
75bf66d629 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 05:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 05:24:37 +02:00
Docker Config Backup
ca212b9e3d Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 04:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 04:54:37 +02:00
Docker Config Backup
bb34d168f6 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 04:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 04:24:37 +02:00
Docker Config Backup
a7b37690b4 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 03:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 03:54:37 +02:00
Docker Config Backup
83b8d8ba59 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 03:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 03:24:37 +02:00
Docker Config Backup
2dac8a0679 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 02:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 02:54:37 +02:00
Docker Config Backup
3596f64ce8 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 02:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 02:24:37 +02:00
Docker Config Backup
fc10e3addc Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 01:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 01:54:37 +02:00
Docker Config Backup
d3c6d6acfe Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 01:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 01:24:37 +02:00
Docker Config Backup
f97a054b7d Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 00:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 00:54:37 +02:00
Docker Config Backup
90c1c2a4f8 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-30 00:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-30 00:24:37 +02:00
Docker Config Backup
a287b75a8f Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 23:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 23:54:37 +02:00
Docker Config Backup
a021750956 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 23:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 23:24:37 +02:00
Docker Config Backup
5c6788665f Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 22:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 22:54:37 +02:00
Docker Config Backup
ce8c01812b Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 22:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 22:24:37 +02:00
Docker Config Backup
a9932d4fd3 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 21:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 21:54:37 +02:00
Docker Config Backup
fa9eb62868 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 21:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 21:24:37 +02:00
Docker Config Backup
92e8ebabe1 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 20:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 20:54:37 +02:00
Docker Config Backup
daa1364069 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 20:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 20:24:37 +02:00
Docker Config Backup
40fb3e6761 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 19:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 19:54:37 +02:00
Docker Config Backup
2dde60e531 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 19:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 19:24:37 +02:00
Docker Config Backup
1773ed4af7 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 18:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 18:54:37 +02:00
Docker Config Backup
ca47d81d6b Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 18:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 18:24:37 +02:00
Docker Config Backup
d3bdffb8f1 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 17:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 17:54:37 +02:00
Docker Config Backup
2204310cec Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 17:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 17:24:37 +02:00
Docker Config Backup
5857be8dc6 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 16:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 16:54:37 +02:00
Docker Config Backup
8e3f09bb7d Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 16:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 16:24:37 +02:00
Docker Config Backup
2fc1eab591 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 15:54:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 15:54:37 +02:00
Docker Config Backup
35762bc4f4 Save before creating restore point: Periodic backup
Auto-saved at 2025-07-29 15:24:37

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 15:24:37 +02:00
Docker Config Backup
e6c22ad29b Auto-save: Updated components/timeshift-spreadsheet.tsx
Auto-saved at 2025-07-29 15:01:45

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 15:01:45 +02:00
4 changed files with 1095 additions and 57 deletions

View File

@@ -13,8 +13,8 @@ const geistMono = Geist_Mono({
}); });
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Create Next App", title: "161",
description: "Generated by create next app", description: "TKB Timeshift Schedule Management Application",
}; };
export default function RootLayout({ export default function RootLayout({

View File

@@ -15,6 +15,10 @@ interface TimeshiftSpreadsheetProps {
export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetProps) { export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetProps) {
const spreadsheetRef = React.useRef<HTMLDivElement>(null) const spreadsheetRef = React.useRef<HTMLDivElement>(null)
const jspreadsheetInstance = React.useRef<unknown>(null) const jspreadsheetInstance = React.useRef<unknown>(null)
const isActiveRef = React.useRef<boolean>(true)
const isMergingRef = React.useRef<boolean>(false)
const isInitializingRef = React.useRef<boolean>(false)
const initTimeoutRef = React.useRef<NodeJS.Timeout | null>(null)
const currentDate = new Date() const currentDate = new Date()
const [selectedMonth, setSelectedMonth] = React.useState<string>((currentDate.getMonth() + 1).toString()) const [selectedMonth, setSelectedMonth] = React.useState<string>((currentDate.getMonth() + 1).toString())
const [selectedYear, setSelectedYear] = React.useState<string>(currentDate.getFullYear().toString()) const [selectedYear, setSelectedYear] = React.useState<string>(currentDate.getFullYear().toString())
@@ -80,7 +84,7 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
console.log("Generated", dayCount, "days of data") console.log("Generated", dayCount, "days of data")
// Complete employee data from Excel file // Complete employee data from Excel file - cleaned up without empty rows, kontrolní řádek, and X BEZ zkušeností s VN
const employees = [ const employees = [
"Pauzer Libor (all in one)", "Pauzer Libor (all in one)",
"Vörös Pavel (NN)", "Vörös Pavel (NN)",
@@ -98,17 +102,20 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
"Zábranský Petr (NN)", "Zábranský Petr (NN)",
"Žemlička Miroslav (NN)", "Žemlička Miroslav (NN)",
"Teslík Hynek (NN)", "Teslík Hynek (NN)",
"X BEZ zkušeností s VN", "Pohotovost IT", // Header - will be made bold
"Pohotovost IT" "Vörös Pavel",
"Janouš Petr",
"Glaser Ondřej",
"Robert Štefan"
] ]
// Add one more column to the right // Add two more columns to the right (CA is formatted, CB will be unformatted)
titleRow.push("") titleRow.push("", "")
dayNameRow.push("") dayNameRow.push("", "")
yearRow.push("") yearRow.push("", "")
monthRow.push("") monthRow.push("", "")
dateRow.push("") dateRow.push("", "")
shiftRow.push("") shiftRow.push("", "")
const employeeRows = employees.map(name => { const employeeRows = employees.map(name => {
const row = [name] const row = [name]
@@ -119,7 +126,7 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
return row return row
}) })
const result = [titleRow, dayNameRow, yearRow, monthRow, dateRow, shiftRow, [""], ...employeeRows] const result = [titleRow, dayNameRow, yearRow, monthRow, dateRow, shiftRow, ...employeeRows]
console.log("Generated", result.length, "rows with", result[0]?.length, "columns") console.log("Generated", result.length, "rows with", result[0]?.length, "columns")
console.log("Title row:", titleRow.slice(0, 10)) console.log("Title row:", titleRow.slice(0, 10))
console.log("Day row:", dayNameRow.slice(0, 10)) console.log("Day row:", dayNameRow.slice(0, 10))
@@ -142,6 +149,34 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
React.useEffect(() => { React.useEffect(() => {
console.log("useEffect triggered - Month:", selectedMonth, "Year:", selectedYear, "Force:", forceUpdate) console.log("useEffect triggered - Month:", selectedMonth, "Year:", selectedYear, "Force:", forceUpdate)
// Clear any existing timeout
if (initTimeoutRef.current) {
console.log("CLEARING: existing timeout, debouncing useEffect")
clearTimeout(initTimeoutRef.current)
}
// Prevent multiple simultaneous initializations with immediate return
if (isInitializingRef.current) {
console.log("BLOCKED: useEffect - already initializing, skipping completely")
return
}
console.log("DEBOUNCING: useEffect with 100ms delay")
// Debounce the initialization to prevent rapid successive calls
initTimeoutRef.current = setTimeout(() => {
console.log("EXECUTING: debounced useEffect after delay")
// Double-check we're still not initializing (could have started between timeout set and execution)
if (isInitializingRef.current) {
console.log("BLOCKED: Still initializing at timeout execution")
return
}
isInitializingRef.current = true
isActiveRef.current = true
const loadJSpreadsheet = async () => { const loadJSpreadsheet = async () => {
console.log("Starting loadJSpreadsheet function") console.log("Starting loadJSpreadsheet function")
@@ -205,10 +240,33 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
if (spreadsheetRef.current && jexcelLib) { if (spreadsheetRef.current && jexcelLib) {
console.log("Initializing spreadsheet...") console.log("Initializing spreadsheet...")
// Clear previous instance // Clear previous instance and reset any merge states
if (jspreadsheetInstance.current) { if (jspreadsheetInstance.current) {
console.log("Destroying previous instance") console.log("Destroying previous instance")
jspreadsheetInstance.current.destroy() try {
const instance = jspreadsheetInstance.current as any
// Clear any existing merges before destroying
if (instance.removeMerge && instance.getMerge) {
try {
const merges = instance.getMerge()
if (merges && Array.isArray(merges)) {
merges.forEach((merge: any) => {
try {
instance.removeMerge(merge.address)
} catch (e) {
// Ignore individual merge removal errors
}
})
}
} catch (e) {
// Ignore merge clearing errors
}
}
instance.destroy()
} catch (error) {
console.error("Error destroying instance:", error)
}
jspreadsheetInstance.current = null
} }
// Use monthly data if month/year selected, otherwise use basic data // Use monthly data if month/year selected, otherwise use basic data
@@ -246,19 +304,53 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
styles[`${colLetter}1`] = "height: 97px;" styles[`${colLetter}1`] = "height: 97px;"
} }
// Make day names row (row 2) taller // Make day names row (row 2) taller and add top and left borders from column B onwards (except last three columns)
for (let col = 0; col < (data[0]?.length || 0); col++) { for (let col = 0; col < (data[0]?.length || 0); col++) {
const colLetter = getExcelColumnName(col) const colLetter = getExcelColumnName(col)
styles[`${colLetter}2`] = "height: 50px;" if (col === 0) {
// First column (A) - just height
styles[`${colLetter}2`] = "height: 50px;"
} else if (colLetter === 'BZ' || colLetter === 'CA' || colLetter === 'CB') {
// Last three columns (BZ, CA, CB) - height only, no borders
styles[`${colLetter}2`] = "height: 50px;"
} else {
// All other columns (B onwards except BZ, CA, CB) - height + top and left borders
styles[`${colLetter}2`] = "height: 50px; border-top: 1px solid #000000; border-left: 1px solid #000000;"
}
}
// Add top border to year row (row 3) from B3 to end of table (excluding A3 and last columns)
for (let col = 1; col < (data[0]?.length || 0) - 2; col++) { // Start from column B (index 1), exclude CA and CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}3`] || ""
styles[`${colLetter}3`] = existingStyle + " border-top: 1px solid #000000;"
}
// Add top border to shift row (row 6) from A6 to end of table (excluding last columns)
for (let col = 0; col < (data[0]?.length || 0) - 2; col++) { // Exclude CA and CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}6`] || ""
styles[`${colLetter}6`] = existingStyle + " border-top: 1px solid #000000;"
}
// Add left borders to columns B onwards for rows 3, 4, 5 (year, month, day)
for (let row = 3; row <= 5; row++) {
for (let col = 1; col < (data[0]?.length || 0) - 2; col++) { // Start from column B (index 1), exclude CA and CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " border-left: 1px solid #000000;"
}
} }
// Style header rows // Style header rows
for (let col = 1; col < (data[0]?.length || 0); col++) { for (let col = 1; col < (data[0]?.length || 0); col++) {
const colLetter = getExcelColumnName(col) const colLetter = getExcelColumnName(col)
// Preserve existing styles (including top border) and add background colors
const existingStyle = styles[`${colLetter}6`] || ""
if (col % 2 === 1) { // Day shifts (odd columns after first) if (col % 2 === 1) { // Day shifts (odd columns after first)
styles[`${colLetter}6`] = "background-color: #ffff00; font-weight: normal;" // Yellow for day, not bold styles[`${colLetter}6`] = existingStyle + " background-color: #ffff00; font-weight: normal;" // Yellow for day, not bold
} else { // Night shifts (even columns after first) } else { // Night shifts (even columns after first)
styles[`${colLetter}6`] = "background-color: #00b0f0; font-weight: normal;" // Blue for night, not bold styles[`${colLetter}6`] = existingStyle + " background-color: #00b0f0; font-weight: normal;" // Blue for night, not bold
} }
} }
@@ -269,21 +361,181 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
const colLetter = getExcelColumnName(col) const colLetter = getExcelColumnName(col)
const nextColLetter = getExcelColumnName(col + 1) const nextColLetter = getExcelColumnName(col + 1)
// Weekend day name row (row 2) - merged cells // Weekend day name row (row 2) - merged cells with conditional borders
styles[`${colLetter}2`] = "background-color: #ffd966; height: 50px;" // Weekend day name with height const hasBorders1 = colLetter !== 'BZ' && colLetter !== 'CA' && colLetter !== 'CB' ? " border-top: 1px solid #000000; border-left: 1px solid #000000;" : ""
styles[`${nextColLetter}2`] = "background-color: #ffd966; height: 50px;" const hasBorders2 = nextColLetter !== 'BZ' && nextColLetter !== 'CA' && nextColLetter !== 'CB' ? " border-top: 1px solid #000000; border-left: 1px solid #000000;" : ""
styles[`${colLetter}2`] = `background-color: #ffd966; height: 50px;${hasBorders1}` // Weekend day name with conditional borders
styles[`${nextColLetter}2`] = `background-color: #ffd966; height: 50px;${hasBorders2}`
// Weekend date columns (rows 3, 4, 5 - year, month, day) // Weekend date columns (rows 3, 4, 5 - year, month, day)
for (let row = 3; row <= 5; row++) { for (let row = 3; row <= 5; row++) {
styles[`${colLetter}${row}`] = "background-color: #ffd966;" // Weekend date values // Preserve existing styles (like borders) and add weekend background
styles[`${nextColLetter}${row}`] = "background-color: #ffd966;" // Weekend date values const existingStyle1 = styles[`${colLetter}${row}`] || ""
const existingStyle2 = styles[`${nextColLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle1 + " background-color: #ffd966;" // Weekend date values
styles[`${nextColLetter}${row}`] = existingStyle2 + " background-color: #ffd966;" // Weekend date values
} }
} }
} }
// Remove formatting specifically from BZ6 and CA6 cells // Remove formatting specifically from BZ6, CA6, and CB6 cells
styles["BZ6"] = "" // Override any formatting for BZ6 styles["BZ6"] = "" // Override any formatting for BZ6
styles["CA6"] = "" // Override any formatting for CA6 styles["CA6"] = "" // Override any formatting for CA6
styles["CB6"] = "" // Override any formatting for CB6
// Remove top border from BZ3 cell
styles["BZ3"] = (styles["BZ3"] || "").replace(" border-top: 1px solid #000000;", "").replace("border-top: 1px solid #000000;", "")
// Add left border to BZ column from row 2 to the last employee row
const totalRows = data.length
const employeeStartRow = 7 // Row 7 is first employee (0-indexed: rows 1-6 are headers, no empty row)
for (let row = 2; row <= totalRows; row++) {
styles[`BZ${row}`] = (styles[`BZ${row}`] || "") + " border-left: 1px solid #000000;"
}
// Add dotted top borders to employee rows (starting from row 8) up to BY column
for (let row = 8; row <= totalRows; row++) {
for (let col = 0; col < (data[0]?.length || 0) - 3; col++) { // All columns except BZ, CA, and CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " border-top: 1px dotted #000000;"
}
}
// Make "Pohotovost IT" header bold (employee index 16, so row 23)
styles["A23"] = "font-weight: bold;" // "Pohotovost IT"
// Set background color for rows 7, 8, and 9 (excluding BZ, CA, and CB columns)
for (let row = 7; row <= 9; row++) {
for (let col = 0; col < (data[0]?.length || 0) - 3; col++) { // All columns except BZ, CA, and CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " background-color: #FCD5B4;"
}
}
// Add left borders to first column of each day (B, D, F, H, etc.) from row 6 to end of table
for (let row = 6; row <= totalRows; row++) {
for (let col = 1; col < (data[0]?.length || 0) - 3; col += 2) { // Start from B (index 1), step by 2, exclude BZ, CA, and CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " border-left: 1px solid #000000;"
}
}
// Add top border to row 28 from A to BY
for (let col = 0; col < (data[0]?.length || 0) - 3; col++) { // All columns except BZ, CA, and CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}28`] || ""
styles[`${colLetter}28`] = existingStyle + " border-top: 1px solid #000000;"
}
// Add alternating row background colors starting from row 10 (every odd row: 10,12,14,16,18,20,22,24,26)
for (let row = 10; row <= totalRows; row += 2) { // Start from 10, increment by 2
for (let col = 0; col < (data[0]?.length || 0) - 3; col++) { // All columns except BZ, CA, and CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " background-color: #D9D9D9;"
}
}
// Add top borders to rows 23 and 24 from A to BY
for (let row of [23, 24]) {
for (let col = 0; col < (data[0]?.length || 0) - 3; col++) { // All columns except BZ, CA, and CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}${row}`] || ""
styles[`${colLetter}${row}`] = existingStyle + " border-top: 1px solid #000000;"
}
}
// Remove left borders from row 23 (day column borders)
for (let col = 1; col < (data[0]?.length || 0) - 3; col += 2) { // Day columns: B, D, F, H, etc., exclude BZ, CA, CB
const colLetter = getExcelColumnName(col)
const existingStyle = styles[`${colLetter}23`] || ""
// Remove left border by replacing it with empty string
styles[`${colLetter}23`] = existingStyle.replace(" border-left: 1px solid #000000;", "").replace("border-left: 1px solid #000000;", "")
}
// Remove left border from BZ23
const existingBZ23Style = styles["BZ23"] || ""
styles["BZ23"] = existingBZ23Style.replace(" border-left: 1px solid #000000;", "").replace("border-left: 1px solid #000000;", "")
// Add top and left borders to merged cell CA2 (CA2:CA6)
const existingCA2Style = styles["CA2"] || ""
styles["CA2"] = existingCA2Style + " border-top: 1px solid #000000; border-left: 1px solid #000000;"
// Add left border to CA column from row 7 to 27 (excluding row 23)
for (let row = 7; row <= 27; row++) {
if (row !== 23) { // Skip row 23 where "Pohotovost IT" is located
const existingCAStyle = styles[`CA${row}`] || ""
styles[`CA${row}`] = existingCAStyle + " border-left: 1px solid #000000;"
}
}
// Add top border to CA23
const existingCA23Style = styles["CA23"] || ""
styles["CA23"] = existingCA23Style + " border-top: 1px solid #000000;"
// Add top border to CA24
const existingCA24Style = styles["CA24"] || ""
styles["CA24"] = existingCA24Style + " border-top: 1px solid #000000;"
// Add top border to CA28
const existingCA28Style = styles["CA28"] || ""
styles["CA28"] = existingCA28Style + " border-top: 1px solid #000000;"
// Add left border to CB column (CB2-CB22 and CB24-CB27, excluding CB23)
for (let row = 2; row <= 27; row++) {
if (row !== 23) { // Skip row 23 where "Pohotovost IT" is located
const existingCBStyle = styles[`CB${row}`] || ""
styles[`CB${row}`] = existingCBStyle + " border-left: 1px solid #000000;"
}
}
// Apply same background colors to CA column as applied to main table rows
// Background color for rows 7, 8, and 9 (same as main table)
for (let row = 7; row <= 9; row++) {
const existingCAStyle = styles[`CA${row}`] || ""
styles[`CA${row}`] = existingCAStyle + " background-color: #FCD5B4;"
}
// Alternating row background colors for CA column starting from row 10 (same as main table)
for (let row = 10; row <= totalRows; row += 2) { // Start from 10, increment by 2
if (row <= 27) { // Only apply to rows up to 27
const existingCAStyle = styles[`CA${row}`] || ""
styles[`CA${row}`] = existingCAStyle + " background-color: #D9D9D9;"
}
}
// Add dotted top borders to CA column for employee rows (starting from row 8, same as main table)
for (let row = 8; row <= 27; row++) {
// Skip rows 23 and 24 as they will get solid borders instead
if (row !== 23 && row !== 24) {
const existingCAStyle = styles[`CA${row}`] || ""
styles[`CA${row}`] = existingCAStyle + " border-top: 1px dotted #000000;"
}
}
// Ensure solid top borders on CA23 and CA24 (override any previous styling)
const existingCA23Style2 = styles["CA23"] || ""
styles["CA23"] = existingCA23Style2.replace(" border-top: 1px dotted #000000;", "") + " border-top: 1px solid #000000;"
const existingCA24Style2 = styles["CA24"] || ""
styles["CA24"] = existingCA24Style2.replace(" border-top: 1px dotted #000000;", "") + " border-top: 1px solid #000000;"
}
// Validate configuration before initializing
if (!data || data.length === 0) {
console.error("Data is empty or undefined:", data)
isInitializingRef.current = false
return
}
if (!columns || columns.length === 0) {
console.error("Columns is empty or undefined:", columns)
isInitializingRef.current = false
return
} }
console.log("Initializing jspreadsheet with config:", { console.log("Initializing jspreadsheet with config:", {
@@ -293,48 +545,327 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
stylesCount: Object.keys(styles).length stylesCount: Object.keys(styles).length
}) })
jspreadsheetInstance.current = (jexcelLib as (el: HTMLElement, config: unknown) => unknown)(spreadsheetRef.current, { const config = {
data: data, data,
columns: columns, columns,
minDimensions: [data[0]?.length || 8, Math.max(data.length + 3, 10)], minDimensions: [data[0]?.length || 8, Math.max(data.length + 3, 10)],
allowInsertRow: true, allowInsertRow: true,
allowInsertColumn: false, allowInsertColumn: false,
allowDeleteRow: true, allowDeleteRow: true,
allowDeleteColumn: false, allowDeleteColumn: false,
contextMenu: true, contextMenu: false,
tableOverflow: true, tableOverflow: true,
tableWidth: "100%", tableWidth: "100%",
tableHeight: "500px", tableHeight: "500px",
style: styles, style: styles,
}) onchange: (instance: any, cell: HTMLElement, x: number, y: number, value: string) => {
console.log("onChange triggered:", { x, y, value, isMerging: isMergingRef.current })
console.log("jspreadsheet initialized:", !!jspreadsheetInstance.current)
// Skip onChange events during merging process to prevent infinite loops
// Apply cell merges for header rows after initialization if (isMergingRef.current) {
setTimeout(() => { console.log("Skipping onChange during merge:", { x, y, value })
if (jspreadsheetInstance.current && selectedMonth && selectedYear) { return
const instance = jspreadsheetInstance.current as any }
if (instance.setMerge) {
try { // Only process if component is still active
// Merge all pairs in rows 1, 2, 3, 4, 5 (title, day names, year, month, day) if (!isActiveRef.current || !jspreadsheetInstance.current) return
const totalCols = data[0]?.length || 0
for (let row = 1; row <= 5; row++) { // Apply rotation to first row (y === 0) when text is entered
for (let col = 1; col < totalCols; col += 2) { if (y === 0 || y === '0') {
const colLetter = getExcelColumnName(col) console.log("First row change detected, applying rotation...", { x, y, value })
try {
// Correct syntax: setMerge(cellAddress, colspan, rowspan) // Use requestAnimationFrame for better DOM timing
instance.setMerge(`${colLetter}${row}`, 2, 1) // 2 columns, 1 row requestAnimationFrame(() => {
} catch (error) { if (!isActiveRef.current || !spreadsheetRef.current) return
// Silently skip merge errors
try {
const table = spreadsheetRef.current?.querySelector('.jexcel tbody')
if (table) {
const rows = table.querySelectorAll('tr')
if (rows[0]) {
const cells = rows[0].querySelectorAll('td')
const targetX = parseInt(String(x))
let targetCell = cells[targetX + 1] as HTMLElement // +1 because first cell is row number
console.log("Initial target cell found:", !!targetCell, "Cell display:", targetCell?.style.display, "Target X:", targetX)
// Handle both merged and non-merged cells
if (targetCell) {
// If target cell is hidden (part of a merge), find the visible merged cell
if (targetCell.style.display === 'none') {
console.log("🔍 Target cell is hidden, finding visible merged cell...")
// Look for visible merged cells that cover this position
let foundCell = null
// Search all visible cells to find which one covers our position
for (let i = 1; i < cells.length; i++) {
const cell = cells[i] as HTMLElement
if (cell && cell.style.display !== 'none' && cell.colSpan && cell.colSpan > 1) {
// Get the starting column of this merged cell
const cellIndex = i - 1 // Subtract 1 for row number cell
const cellSpan = cell.colSpan
// Check if our target position falls within this merged cell's span
if (cellIndex <= targetX && targetX < cellIndex + cellSpan) {
foundCell = cell
console.log("🎯 Found covering merged cell:", {
cellIndex,
cellSpan,
targetX,
covers: `${cellIndex} to ${cellIndex + cellSpan - 1}`
})
break
}
}
}
if (foundCell) {
targetCell = foundCell
console.log("✅ Using merged cell for rotation")
} else {
console.warn("❌ Could not find visible merged cell for position", targetX)
// Try to use the target cell anyway, even if hidden
console.log("🔄 Attempting to use hidden cell directly")
}
} else {
console.log("✅ Target cell is visible, using directly")
}
}
if (targetCell) {
const displayValue = value !== undefined && value !== null ? String(value).trim() : ''
console.log("Processing value:", displayValue, "for cell at position:", targetX)
if (displayValue) {
// Force clear any existing content first
targetCell.innerHTML = ''
// Apply rotation with improved styling
const rotatedDiv = document.createElement('div')
rotatedDiv.style.cssText = `
transform: rotate(-90deg) !important;
font-size: 12px !important;
height: 80px !important;
width: 20px !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
white-space: nowrap !important;
margin: 0 auto !important;
transform-origin: center center !important;
position: relative !important;
color: #000 !important;
background: transparent !important;
`
rotatedDiv.textContent = displayValue
targetCell.appendChild(rotatedDiv)
console.log("✅ Rotation applied successfully to cell with value:", displayValue)
} else {
// Clear cell content but maintain structure
targetCell.innerHTML = ''
console.log("✅ Cleared cell content")
}
} else {
console.warn("❌ Target cell not found at index:", targetX + 1)
}
} else {
console.warn("❌ First row not found")
} }
} else {
console.warn("❌ Table not found")
} }
} catch (error) {
console.error("❌ Error applying rotation:", error)
} }
} catch (error) { })
console.error("Error during merging:", error)
}
} }
} }
}, 100) }
console.log("Config validation passed, creating jspreadsheet instance...")
console.log("Full config object:", JSON.stringify(config, null, 2))
console.log("Config keys:", Object.keys(config))
console.log("Data sample:", data.slice(0, 2))
console.log("Columns sample:", columns.slice(0, 3))
try {
jspreadsheetInstance.current = (jexcelLib as (el: HTMLElement, config: unknown) => unknown)(spreadsheetRef.current, config)
console.log("jspreadsheet initialized:", !!jspreadsheetInstance.current)
} catch (error) {
console.error("Error initializing jspreadsheet:", error)
console.error("Config that caused error:", JSON.stringify(config, null, 2))
console.error("Config keys that caused error:", Object.keys(config))
console.error("Data that caused error:", data?.slice(0, 2))
console.error("Columns that caused error:", columns?.slice(0, 3))
isInitializingRef.current = false
return
}
// Additional event listener for first row rotation as fallback
setTimeout(() => {
if (!isActiveRef.current || !spreadsheetRef.current) return
const table = spreadsheetRef.current?.querySelector('.jexcel tbody')
if (table) {
// Add input event listeners to first row cells
const firstRow = table.querySelector('tr:first-child')
if (firstRow) {
const cells = firstRow.querySelectorAll('td')
cells.forEach((cell, index) => {
if (index > 0) { // Skip row number cell
const cellElement = cell as HTMLElement
// Create rotation function for reuse
const applyRotation = (target: HTMLElement, value: string) => {
if (value.trim()) {
requestAnimationFrame(() => {
target.innerHTML = `<div style="
transform: rotate(-90deg) !important;
font-size: 12px !important;
height: 80px !important;
width: 20px !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
white-space: nowrap !important;
margin: 0 auto !important;
transform-origin: center center !important;
position: relative !important;
color: #000 !important;
background: transparent !important;
">${value.trim()}</div>`
console.log("🎯 Direct rotation applied via event listener")
})
} else {
target.innerHTML = ''
}
}
// Listen for input events on the cell
cellElement.addEventListener('input', (e) => {
const target = e.target as HTMLElement
const value = target.textContent || target.innerText || ''
console.log("🎯 Direct input event on first row cell:", { index, value, colSpan: cellElement.colSpan })
applyRotation(target, value)
})
// Also listen for blur events
cellElement.addEventListener('blur', (e) => {
const target = e.target as HTMLElement
const value = target.textContent || target.innerText || ''
console.log("🎯 Blur event on first row cell:", { index, value, colSpan: cellElement.colSpan })
applyRotation(target, value)
})
// Listen for keyup events as well for immediate feedback
cellElement.addEventListener('keyup', (e) => {
const target = e.target as HTMLElement
const value = target.textContent || target.innerText || ''
console.log("🎯 Keyup event on first row cell:", { index, value, colSpan: cellElement.colSpan })
if (value.trim()) {
applyRotation(target, value)
}
})
}
})
}
}
}, 500)
// DISABLED: Mutation observer for first row rotation
// This was causing popup issues when switching tabs
// TODO: Implement a different approach for first row rotation if needed
// Apply cell merges for header rows after initialization - with improved error handling
setTimeout(() => {
if (!isActiveRef.current || !jspreadsheetInstance.current || !selectedMonth || !selectedYear) return
try {
const instance = jspreadsheetInstance.current as any
if (!instance.setMerge) return
console.log("Starting cell merging process...")
// Set merging flag to prevent onChange events during merge process
isMergingRef.current = true
// Clear any existing merges first to start fresh
if (instance.removeMerge && instance.getMerge) {
try {
const existingMerges = instance.getMerge()
if (existingMerges && Array.isArray(existingMerges)) {
existingMerges.forEach((merge: any) => {
try {
instance.removeMerge(merge.address)
} catch (e) {
// Ignore errors - merge might not exist
}
})
}
} catch (e) {
// Ignore errors getting existing merges
}
}
// Now apply new merges
const totalCols = data[0]?.length || 0
let mergeCount = 0
for (let row = 1; row <= 5; row++) {
for (let col = 1; col < totalCols; col += 2) {
// Double check we're still active
if (!isActiveRef.current || !jspreadsheetInstance.current) {
console.log("Component became inactive during merging")
isMergingRef.current = false
return
}
const colLetter = getExcelColumnName(col)
// Skip merging for BZ and CA columns
if (colLetter === 'BZ' || colLetter === 'CA') {
continue
}
try {
const cellAddress = `${colLetter}${row}`
console.log(`Attempting to merge: ${cellAddress}`)
instance.setMerge(cellAddress, 2, 1) // 2 columns, 1 row
mergeCount++
} catch (error) {
console.warn(`Failed to merge ${colLetter}${row}:`, error.message)
// Continue with other merges even if one fails
}
}
}
console.log(`Successfully applied ${mergeCount} cell merges`)
// Merge CA2 to CA6 (5 rows, 1 column)
try {
console.log("Attempting to merge CA2:CA6")
instance.setMerge("CA2", 1, 5) // 1 column, 5 rows (CA2, CA3, CA4, CA5, CA6)
console.log("Successfully merged CA2:CA6")
} catch (error) {
console.warn("Failed to merge CA2:CA6:", error.message)
}
// Clear merging flag after completion
isMergingRef.current = false
} catch (error) {
console.error("General error during cell merging:", error)
isMergingRef.current = false
}
}, 300) // Increased timeout to ensure spreadsheet is fully ready
// Clear initialization flag after successful setup - increased timeout to prevent rapid re-initializations
setTimeout(() => {
isInitializingRef.current = false
initTimeoutRef.current = null
console.log("Initialization completed, flag and timeout cleared")
}, 2000) // Extended to 2 seconds to ensure complete initialization
// Apply counter-clockwise rotation to data values only (exclude second column which contains field labels) // Apply counter-clockwise rotation to data values only (exclude second column which contains field labels)
setTimeout(() => { setTimeout(() => {
@@ -343,8 +874,8 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
const rows = table.querySelectorAll('tr') const rows = table.querySelectorAll('tr')
const totalCells = data[0]?.length || 0 const totalCells = data[0]?.length || 0
// Rotate data values in rows 2, 3, 4, 5, 6 (day names, year, month, day, shifts) // Rotate data values in rows 1, 2, 3, 4, 5, 6 (first row, day names, year, month, day, shifts)
;[1, 2, 3, 4, 5].forEach(rowIndex => { ;[0, 1, 2, 3, 4, 5].forEach(rowIndex => {
if (rows[rowIndex]) { if (rows[rowIndex]) {
const cells = rows[rowIndex].querySelectorAll('td') const cells = rows[rowIndex].querySelectorAll('td')
cells.forEach((cell, cellIndex) => { cells.forEach((cell, cellIndex) => {
@@ -353,7 +884,9 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
const originalText = cell.textContent?.trim() const originalText = cell.textContent?.trim()
if (originalText) { if (originalText) {
// Use 12px font for all rotated values (date values, day names, and shifts) // Use 12px font for all rotated values (date values, day names, and shifts)
cell.innerHTML = `<div style="transform: rotate(-90deg); font-size: 12px; height: 20px; display: flex; align-items: center; justify-content: center; white-space: nowrap;">${originalText}</div>` // For first row (rowIndex 0), ensure width: 100% for better text display
const extraStyle = rowIndex === 0 ? ' width: 100%;' : ''
cell.innerHTML = `<div style="transform: rotate(-90deg); font-size: 12px; height: 20px; display: flex; align-items: center; justify-content: center; white-space: nowrap;${extraStyle}">${originalText}</div>`
} }
} }
}) })
@@ -361,7 +894,7 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
}) })
// Make only "Pohotovost TKB" bold, keep other field labels regular and ensure they're not rotated // Make only "Pohotovost TKB" bold, keep other field labels regular and ensure they're not rotated
;[0, 2, 3, 4, 5].forEach(rowIndex => { ;[0, 1, 2, 3, 4, 5].forEach(rowIndex => {
if (rows[rowIndex]) { if (rows[rowIndex]) {
const cells = rows[rowIndex].querySelectorAll('td') const cells = rows[rowIndex].querySelectorAll('td')
if (cells[1]) { // Second column (index 1) if (cells[1]) { // Second column (index 1)
@@ -380,17 +913,30 @@ export function TimeshiftSpreadsheet({ teamId, teamName }: TimeshiftSpreadsheetP
} else { } else {
console.log("Cannot initialize - missing ref or jexcel library") console.log("Cannot initialize - missing ref or jexcel library")
isInitializingRef.current = false
} }
} }
console.log("Calling loadJSpreadsheet...") console.log("Calling loadJSpreadsheet...")
loadJSpreadsheet().catch(error => { loadJSpreadsheet().catch(error => {
console.error("Error in loadJSpreadsheet:", error) console.error("Error in loadJSpreadsheet:", error)
isInitializingRef.current = false
}) })
}, 100) // 100ms debounce delay
return () => { return () => {
// Clear timeout on cleanup
if (initTimeoutRef.current) {
clearTimeout(initTimeoutRef.current)
initTimeoutRef.current = null
}
isActiveRef.current = false
isMergingRef.current = false
isInitializingRef.current = false
if (jspreadsheetInstance.current) { if (jspreadsheetInstance.current) {
jspreadsheetInstance.current.destroy() jspreadsheetInstance.current.destroy()
jspreadsheetInstance.current = null
} }
} }
}, [teamId, selectedMonth, selectedYear, forceUpdate]) }, [teamId, selectedMonth, selectedYear, forceUpdate])

View File

@@ -56,3 +56,249 @@
2025-07-29 14:54:37 +02:00: (node:652376) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead. 2025-07-29 14:54:37 +02:00: (node:652376) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
2025-07-29 14:54:37 +02:00: (Use `node --trace-deprecation ...` to show where the warning was created) 2025-07-29 14:54:37 +02:00: (Use `node --trace-deprecation ...` to show where the warning was created)
2025-07-29 14:54:42 +02:00: 🔖 Creating restore point... 2025-07-29 14:54:42 +02:00: 🔖 Creating restore point...
2025-07-29 14:54:48 +02:00: ✅ Restore point created
2025-07-29 15:01:15 +02:00: 📝 File changed: components/timeshift-spreadsheet.tsx (change)
2025-07-29 15:01:15 +02:00: 📝 File changed: components/timeshift-spreadsheet.tsx (change)
2025-07-29 15:01:15 +02:00: 📝 File changed: components/timeshift-spreadsheet.tsx (change)
2025-07-29 15:01:45 +02:00: 🔄 Performing auto-commit...
2025-07-29 15:01:52 +02:00: ✅ Auto-commit successful
2025-07-29 15:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 15:24:39 +02:00: ✅ Restore point created
2025-07-29 15:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 15:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 15:54:39 +02:00: ✅ Restore point created
2025-07-29 16:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 16:24:39 +02:00: ✅ Restore point created
2025-07-29 16:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 16:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 16:54:39 +02:00: ✅ Restore point created
2025-07-29 17:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 17:24:40 +02:00: ✅ Restore point created
2025-07-29 17:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 17:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 17:54:40 +02:00: ✅ Restore point created
2025-07-29 18:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 18:24:39 +02:00: ✅ Restore point created
2025-07-29 18:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 18:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 18:54:39 +02:00: ✅ Restore point created
2025-07-29 19:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 19:24:39 +02:00: ✅ Restore point created
2025-07-29 19:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 19:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 19:54:39 +02:00: ✅ Restore point created
2025-07-29 20:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 20:24:41 +02:00: ✅ Restore point created
2025-07-29 20:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 20:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 20:54:41 +02:00: ✅ Restore point created
2025-07-29 21:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 21:24:40 +02:00: ✅ Restore point created
2025-07-29 21:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 21:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 21:54:40 +02:00: ✅ Restore point created
2025-07-29 22:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 22:24:40 +02:00: ✅ Restore point created
2025-07-29 22:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 22:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 22:54:40 +02:00: ✅ Restore point created
2025-07-29 23:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 23:24:40 +02:00: ✅ Restore point created
2025-07-29 23:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 23:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 23:54:40 +02:00: ✅ Restore point created
2025-07-30 00:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 00:24:40 +02:00: ✅ Restore point created
2025-07-30 00:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 00:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 00:54:41 +02:00: ✅ Restore point created
2025-07-30 01:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 01:24:41 +02:00: ✅ Restore point created
2025-07-30 01:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 01:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 01:54:40 +02:00: ✅ Restore point created
2025-07-30 02:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 02:24:42 +02:00: ✅ Restore point created
2025-07-30 02:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 02:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 02:54:44 +02:00: ✅ Restore point created
2025-07-30 03:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 03:24:41 +02:00: ✅ Restore point created
2025-07-30 03:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 03:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 03:54:41 +02:00: ✅ Restore point created
2025-07-30 04:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 04:24:48 +02:00: ✅ Restore point created
2025-07-30 04:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 04:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 04:54:41 +02:00: ✅ Restore point created
2025-07-30 05:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 05:25:01 +02:00: ✅ Restore point created
2025-07-30 05:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 05:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 05:54:42 +02:00: ✅ Restore point created
2025-07-30 06:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 06:24:42 +02:00: ✅ Restore point created
2025-07-30 06:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 06:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 06:54:42 +02:00: ✅ Restore point created
2025-07-30 07:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 07:24:44 +02:00: ✅ Restore point created
2025-07-30 07:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 07:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 07:54:43 +02:00: ✅ Restore point created
2025-07-30 08:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 08:24:45 +02:00: ✅ Restore point created
2025-07-30 08:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 08:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 08:54:46 +02:00: ✅ Restore point created
2025-07-30 09:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 09:24:50 +02:00: ✅ Restore point created
2025-07-30 09:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 09:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 09:56:10 +02:00: ✅ Restore point created
2025-07-30 10:07:58 +02:00: 📝 File changed: app/layout.tsx (change)
2025-07-30 10:07:58 +02:00: 📝 File changed: app/layout.tsx (change)
2025-07-30 10:07:58 +02:00: 📝 File changed: app/layout.tsx (change)
2025-07-30 10:08:28 +02:00: 🔄 Performing auto-commit...
2025-07-30 10:08:37 +02:00: ✅ Auto-commit successful
2025-07-30 10:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 10:24:48 +02:00: ✅ Restore point created
2025-07-30 10:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 10:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 10:56:09 +02:00: ✅ Restore point created
2025-07-30 11:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 11:25:00 +02:00: ✅ Restore point created
2025-07-30 11:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 11:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 11:54:53 +02:00: ✅ Restore point created
2025-07-30 12:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 12:26:09 +02:00: ✅ Restore point created
2025-07-30 12:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 12:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 12:56:08 +02:00: ✅ Restore point created
2025-07-30 13:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 13:26:08 +02:00: ✅ Restore point created
2025-07-30 13:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 13:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 13:56:10 +02:00: ✅ Restore point created
2025-07-30 14:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 14:26:12 +02:00: ✅ Restore point created
2025-07-30 14:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 14:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 14:56:16 +02:00: ✅ Restore point created
2025-07-30 15:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 15:26:08 +02:00: ✅ Restore point created
2025-07-30 15:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 15:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 15:56:10 +02:00: ✅ Restore point created
2025-07-30 16:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 16:26:09 +02:00: ✅ Restore point created
2025-07-30 16:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 16:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 16:56:09 +02:00: ✅ Restore point created
2025-07-30 17:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 17:26:09 +02:00: ✅ Restore point created
2025-07-30 17:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 17:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 17:56:11 +02:00: ✅ Restore point created
2025-07-30 18:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 18:26:13 +02:00: ✅ Restore point created
2025-07-30 18:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 18:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 18:55:27 +02:00: ✅ Restore point created
2025-07-30 19:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 19:25:22 +02:00: ✅ Restore point created
2025-07-30 19:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 19:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 19:54:48 +02:00: ✅ Restore point created
2025-07-30 20:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 20:26:09 +02:00: ✅ Restore point created
2025-07-30 20:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 20:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 20:54:50 +02:00: ✅ Restore point created
2025-07-30 21:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 21:26:08 +02:00: ✅ Restore point created
2025-07-30 21:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 21:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 21:54:52 +02:00: ✅ Restore point created
2025-07-30 22:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 22:26:08 +02:00: ✅ Restore point created
2025-07-30 22:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 22:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 22:56:09 +02:00: ✅ Restore point created
2025-07-30 23:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 23:26:11 +02:00: ✅ Restore point created
2025-07-30 23:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 23:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 23:56:09 +02:00: ✅ Restore point created
2025-07-31 00:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 00:26:10 +02:00: ✅ Restore point created
2025-07-31 00:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 00:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 00:55:03 +02:00: ✅ Restore point created
2025-07-31 01:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 01:26:11 +02:00: ✅ Restore point created
2025-07-31 01:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 01:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 01:56:09 +02:00: ✅ Restore point created
2025-07-31 02:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 02:26:07 +02:00: ✅ Restore point created
2025-07-31 02:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 02:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 02:56:07 +02:00: ✅ Restore point created
2025-07-31 03:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 03:24:44 +02:00: ✅ Restore point created
2025-07-31 03:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 03:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 03:54:47 +02:00: ✅ Restore point created
2025-07-31 04:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 04:24:51 +02:00: ✅ Restore point created
2025-07-31 04:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 04:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 04:56:08 +02:00: ✅ Restore point created
2025-07-31 05:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 05:26:11 +02:00: ✅ Restore point created
2025-07-31 05:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 05:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 05:56:09 +02:00: ✅ Restore point created
2025-07-31 06:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 06:26:08 +02:00: ✅ Restore point created
2025-07-31 06:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 06:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 06:56:11 +02:00: ✅ Restore point created
2025-07-31 07:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 07:26:12 +02:00: ✅ Restore point created
2025-07-31 07:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 07:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 07:56:09 +02:00: ✅ Restore point created
2025-07-31 08:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 08:26:09 +02:00: ✅ Restore point created
2025-07-31 08:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 08:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 08:55:17 +02:00: ✅ Restore point created
2025-07-31 09:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 09:26:08 +02:00: ✅ Restore point created
2025-07-31 09:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 09:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 09:56:11 +02:00: ✅ Restore point created
2025-07-31 10:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 10:26:13 +02:00: ✅ Restore point created
2025-07-31 10:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 10:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 10:56:08 +02:00: ✅ Restore point created
2025-07-31 11:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 11:26:08 +02:00: ✅ Restore point created
2025-07-31 11:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 11:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 11:56:08 +02:00: ✅ Restore point created
2025-07-31 12:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 12:26:08 +02:00: ✅ Restore point created
2025-07-31 12:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 12:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 12:56:13 +02:00: ✅ Restore point created
2025-07-31 13:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 13:24:40 +02:00: ✅ Restore point created
2025-07-31 13:42:49 +02:00:
2025-07-31 13:42:49 +02:00: 🛑 Stopping auto-commit watcher...
2025-07-31 13:42:49 +02:00: 💾 Saving final changes...

View File

@@ -52,3 +52,249 @@
2025-07-29 14:54:37 +02:00: ./auto-commit.sh list 2025-07-29 14:54:37 +02:00: ./auto-commit.sh list
2025-07-29 14:54:37 +02:00: ./auto-commit.sh cleanup 2025-07-29 14:54:37 +02:00: ./auto-commit.sh cleanup
2025-07-29 14:54:42 +02:00: 🔖 Creating restore point... 2025-07-29 14:54:42 +02:00: 🔖 Creating restore point...
2025-07-29 14:54:48 +02:00: ✅ Restore point created
2025-07-29 15:01:15 +02:00: 📝 File changed: components/timeshift-spreadsheet.tsx (change)
2025-07-29 15:01:15 +02:00: 📝 File changed: components/timeshift-spreadsheet.tsx (change)
2025-07-29 15:01:15 +02:00: 📝 File changed: components/timeshift-spreadsheet.tsx (change)
2025-07-29 15:01:45 +02:00: 🔄 Performing auto-commit...
2025-07-29 15:01:52 +02:00: ✅ Auto-commit successful
2025-07-29 15:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 15:24:39 +02:00: ✅ Restore point created
2025-07-29 15:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 15:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 15:54:39 +02:00: ✅ Restore point created
2025-07-29 16:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 16:24:39 +02:00: ✅ Restore point created
2025-07-29 16:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 16:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 16:54:39 +02:00: ✅ Restore point created
2025-07-29 17:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 17:24:40 +02:00: ✅ Restore point created
2025-07-29 17:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 17:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 17:54:40 +02:00: ✅ Restore point created
2025-07-29 18:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 18:24:39 +02:00: ✅ Restore point created
2025-07-29 18:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 18:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 18:54:39 +02:00: ✅ Restore point created
2025-07-29 19:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 19:24:39 +02:00: ✅ Restore point created
2025-07-29 19:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 19:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 19:54:39 +02:00: ✅ Restore point created
2025-07-29 20:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 20:24:41 +02:00: ✅ Restore point created
2025-07-29 20:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 20:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 20:54:41 +02:00: ✅ Restore point created
2025-07-29 21:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 21:24:40 +02:00: ✅ Restore point created
2025-07-29 21:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 21:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 21:54:40 +02:00: ✅ Restore point created
2025-07-29 22:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 22:24:40 +02:00: ✅ Restore point created
2025-07-29 22:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 22:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 22:54:40 +02:00: ✅ Restore point created
2025-07-29 23:24:37 +02:00: 🔖 Creating restore point...
2025-07-29 23:24:40 +02:00: ✅ Restore point created
2025-07-29 23:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-29 23:54:37 +02:00: 🔖 Creating restore point...
2025-07-29 23:54:40 +02:00: ✅ Restore point created
2025-07-30 00:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 00:24:40 +02:00: ✅ Restore point created
2025-07-30 00:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 00:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 00:54:41 +02:00: ✅ Restore point created
2025-07-30 01:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 01:24:41 +02:00: ✅ Restore point created
2025-07-30 01:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 01:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 01:54:40 +02:00: ✅ Restore point created
2025-07-30 02:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 02:24:42 +02:00: ✅ Restore point created
2025-07-30 02:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 02:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 02:54:44 +02:00: ✅ Restore point created
2025-07-30 03:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 03:24:41 +02:00: ✅ Restore point created
2025-07-30 03:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 03:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 03:54:41 +02:00: ✅ Restore point created
2025-07-30 04:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 04:24:48 +02:00: ✅ Restore point created
2025-07-30 04:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 04:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 04:54:41 +02:00: ✅ Restore point created
2025-07-30 05:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 05:25:01 +02:00: ✅ Restore point created
2025-07-30 05:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 05:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 05:54:42 +02:00: ✅ Restore point created
2025-07-30 06:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 06:24:42 +02:00: ✅ Restore point created
2025-07-30 06:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 06:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 06:54:42 +02:00: ✅ Restore point created
2025-07-30 07:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 07:24:44 +02:00: ✅ Restore point created
2025-07-30 07:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 07:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 07:54:43 +02:00: ✅ Restore point created
2025-07-30 08:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 08:24:45 +02:00: ✅ Restore point created
2025-07-30 08:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 08:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 08:54:46 +02:00: ✅ Restore point created
2025-07-30 09:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 09:24:50 +02:00: ✅ Restore point created
2025-07-30 09:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 09:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 09:56:10 +02:00: ✅ Restore point created
2025-07-30 10:07:58 +02:00: 📝 File changed: app/layout.tsx (change)
2025-07-30 10:07:58 +02:00: 📝 File changed: app/layout.tsx (change)
2025-07-30 10:07:58 +02:00: 📝 File changed: app/layout.tsx (change)
2025-07-30 10:08:28 +02:00: 🔄 Performing auto-commit...
2025-07-30 10:08:37 +02:00: ✅ Auto-commit successful
2025-07-30 10:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 10:24:48 +02:00: ✅ Restore point created
2025-07-30 10:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 10:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 10:56:09 +02:00: ✅ Restore point created
2025-07-30 11:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 11:25:00 +02:00: ✅ Restore point created
2025-07-30 11:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 11:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 11:54:53 +02:00: ✅ Restore point created
2025-07-30 12:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 12:26:09 +02:00: ✅ Restore point created
2025-07-30 12:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 12:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 12:56:08 +02:00: ✅ Restore point created
2025-07-30 13:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 13:26:08 +02:00: ✅ Restore point created
2025-07-30 13:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 13:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 13:56:10 +02:00: ✅ Restore point created
2025-07-30 14:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 14:26:12 +02:00: ✅ Restore point created
2025-07-30 14:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 14:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 14:56:16 +02:00: ✅ Restore point created
2025-07-30 15:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 15:26:08 +02:00: ✅ Restore point created
2025-07-30 15:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 15:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 15:56:10 +02:00: ✅ Restore point created
2025-07-30 16:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 16:26:09 +02:00: ✅ Restore point created
2025-07-30 16:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 16:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 16:56:09 +02:00: ✅ Restore point created
2025-07-30 17:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 17:26:09 +02:00: ✅ Restore point created
2025-07-30 17:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 17:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 17:56:11 +02:00: ✅ Restore point created
2025-07-30 18:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 18:26:13 +02:00: ✅ Restore point created
2025-07-30 18:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 18:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 18:55:27 +02:00: ✅ Restore point created
2025-07-30 19:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 19:25:22 +02:00: ✅ Restore point created
2025-07-30 19:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 19:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 19:54:48 +02:00: ✅ Restore point created
2025-07-30 20:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 20:26:09 +02:00: ✅ Restore point created
2025-07-30 20:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 20:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 20:54:50 +02:00: ✅ Restore point created
2025-07-30 21:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 21:26:08 +02:00: ✅ Restore point created
2025-07-30 21:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 21:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 21:54:52 +02:00: ✅ Restore point created
2025-07-30 22:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 22:26:08 +02:00: ✅ Restore point created
2025-07-30 22:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 22:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 22:56:09 +02:00: ✅ Restore point created
2025-07-30 23:24:37 +02:00: 🔖 Creating restore point...
2025-07-30 23:26:11 +02:00: ✅ Restore point created
2025-07-30 23:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-30 23:54:37 +02:00: 🔖 Creating restore point...
2025-07-30 23:56:09 +02:00: ✅ Restore point created
2025-07-31 00:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 00:26:10 +02:00: ✅ Restore point created
2025-07-31 00:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 00:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 00:55:03 +02:00: ✅ Restore point created
2025-07-31 01:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 01:26:11 +02:00: ✅ Restore point created
2025-07-31 01:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 01:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 01:56:09 +02:00: ✅ Restore point created
2025-07-31 02:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 02:26:07 +02:00: ✅ Restore point created
2025-07-31 02:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 02:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 02:56:07 +02:00: ✅ Restore point created
2025-07-31 03:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 03:24:44 +02:00: ✅ Restore point created
2025-07-31 03:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 03:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 03:54:47 +02:00: ✅ Restore point created
2025-07-31 04:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 04:24:51 +02:00: ✅ Restore point created
2025-07-31 04:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 04:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 04:56:08 +02:00: ✅ Restore point created
2025-07-31 05:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 05:26:11 +02:00: ✅ Restore point created
2025-07-31 05:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 05:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 05:56:09 +02:00: ✅ Restore point created
2025-07-31 06:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 06:26:08 +02:00: ✅ Restore point created
2025-07-31 06:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 06:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 06:56:11 +02:00: ✅ Restore point created
2025-07-31 07:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 07:26:12 +02:00: ✅ Restore point created
2025-07-31 07:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 07:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 07:56:09 +02:00: ✅ Restore point created
2025-07-31 08:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 08:26:09 +02:00: ✅ Restore point created
2025-07-31 08:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 08:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 08:55:17 +02:00: ✅ Restore point created
2025-07-31 09:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 09:26:08 +02:00: ✅ Restore point created
2025-07-31 09:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 09:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 09:56:11 +02:00: ✅ Restore point created
2025-07-31 10:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 10:26:13 +02:00: ✅ Restore point created
2025-07-31 10:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 10:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 10:56:08 +02:00: ✅ Restore point created
2025-07-31 11:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 11:26:08 +02:00: ✅ Restore point created
2025-07-31 11:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 11:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 11:56:08 +02:00: ✅ Restore point created
2025-07-31 12:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 12:26:08 +02:00: ✅ Restore point created
2025-07-31 12:54:37 +02:00: 🔄 Hourly reset: Commit counter reset to 0
2025-07-31 12:54:37 +02:00: 🔖 Creating restore point...
2025-07-31 12:56:13 +02:00: ✅ Restore point created
2025-07-31 13:24:37 +02:00: 🔖 Creating restore point...
2025-07-31 13:24:40 +02:00: ✅ Restore point created
2025-07-31 13:42:49 +02:00:
2025-07-31 13:42:49 +02:00: 🛑 Stopping auto-commit watcher...
2025-07-31 13:42:49 +02:00: 💾 Saving final changes...