Commit Graph

118 Commits

Author SHA1 Message Date
Scarriffle
6316ed3a6b feat(web): theme import/export, more themable colors, hideable local/ical calendars
Theme:
- Export/import themes via UI as <date>_<time>.theme (JSON, readable keys,
  link to THEME.md). Import is partial-aware: only present params are written
  (server accepts partial); prompts before importing files with unknown params.
- Dynamic favicon + theme-color tinted to the primary colour on load/save.
- New themable colours: general hover-highlight, day hover/selected/bg,
  today background, plus two unified sidebar action-icon colours
  (inactive/active) covering bell, hide, delete and read-only icons.
- All new colours are per-setting syncable; documented in THEME.md.

UX:
- Styled confirm dialog (#modal-confirm) replaces window.confirm() for
  calendar delete and account disconnect.
- Birthday/local calendars and iCal subscriptions can now be hidden from the
  sidebar via Settings (new sidebar_hidden column + hide toggle).

Backend: additive nullable columns + idempotent migrations for user_settings
colours and local_calendars/ical_subscriptions.sidebar_hidden.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 13:20:30 +02:00
Scarriffle
7a89cc44f8 Web: settings page nav/header follow the surface colour too
The settings modal's own left nav and header were on --bg-app; point them at
--bg-sidebar / --bg-topbar so they track surface_color like the main sidebar.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 22:08:22 +02:00
Scarriffle
131f6b496d Add configurable surface/sidebar colour + clearer sync-icon state
- new user_settings.surface_color (nullable, device-local default, not synced):
  drives the web sidebar / top bar / surfaces; NULL derives from bg_color as
  before. Added to schema, migration, GET/PUT, NULLABLE_OVERRIDES, DEFAULT_SYNC.
- web: surface colour row in the settings table; applyTheme derives the whole
  surface family from it
- web: per-row sync icon now has real styling — ON shows the primary-tinted
  glyph on a pill, OFF shows a slashed, muted glyph (was previously unstyled,
  so synced/not-synced looked identical)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 22:01:16 +02:00
Scarriffle
4ab07ddcc3 Web polish from testing feedback + admin role toggle
- style the settings-table dropdowns for the dark theme (were white)
- share-icon picker on one even row (no lopsided wrap)
- more breathing room between colour hex and swatch
- user management: promote/demote admin (new PUT /users/{id}/admin,
  guarded against self-change and removing the last admin)
- calendar management table: clip/ellipsis cells so narrow columns no
  longer overlap (full-width detail rows still wrap)
- centralise default colours: utils.applyTheme now derives every fallback
  from settings-sync.DEFAULT_COLORS (single place for coders to edit)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 21:25:01 +02:00
Scarriffle
137694ed98 Web: unified settings sync table with per-setting sync toggles
Replace the ad-hoc appearance panel with a uniform table (sync icon | name |
value): dropdowns instead of button groups, every colour with a reset to a
canonical default, a per-row sync toggle, and a global "sync all" master
switch.

- new settings-sync.js: canonical default colours, declarative table
  definition, browser-local value copy, effective-value resolution
- calendar.js: generalised sync engine (pull applies only synced keys from the
  server, save pushes only synced keys + the flag map), unified the two save
  buttons into one, dropped the dead text/line-contrast code, moved default
  duration into the appearance table, effective UI language on load
- account settings (private visibility, group calendar, hide profile) stay in a
  dedicated profile block, not the sync table
- app.css: settings table / sync toggle / sync icon styles
- i18n: sync-all / sync-this / share-icon strings; sw cache bump

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 21:07:26 +02:00
Scarriffle
0ce77ccdf8 Add drag-resizable columns to the calendar settings table
Column widths are draggable via a handle on each header's right edge and
persisted in localStorage (re-applied on re-render). Uses fixed table layout
locked to measured px widths so resizing one column doesn't reflow the others.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 21:06:36 +02:00
Scarriffle
1a30b4066a Fix: don't squeeze the Kalender settings table into the 680px column
The reading-column max-width added for the profile panel also constrained the
wide calendar table, forcing a half-width horizontal scroll. Exempt
#settings-panel-accounts so the table uses the full width.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 20:49:26 +02:00
Scarriffle
19258096e2 Tidy settings layout (web)
- constrain settings panels to a 680px reading column so fields no longer
  stretch edge-to-edge on wide screens (main "looks bad" cause)
- fix the app-password "Erstellen" button rendering centred below the input:
  .app-pw-create inherited flex-direction:column from .form-group; force row so
  it sits inline to the right of the field

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 04:31:12 +02:00
Scarriffle
6baa07379f Rework birthdays to a single calendar + UI fixes (web)
- one dedicated birthday calendar per user; enable it in Settings > Calendars
  (or from the New-birthday dialog) — it then shows in the sidebar like any
  calendar (colour/visibility)
- New-birthday dialog: no target picker; day/month selects + a year field that
  hides when "year unknown"; fixed the year-unknown checkbox layout
- create split-button is now one seamless pill; the caret opens the menu
- Settings > Calendars gains a Birthdays section (enable + notify-days-before)
- removed the birthday toggle from the generic new-calendar modal
- profile settings: right-align the section save button for consistency
- bump service-worker cache to v25 so assets refresh

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 04:20:49 +02:00
Scarriffle
eb0684b99c Add birthday feature (web)
- views render display_title (age) and a cake icon for is_birthday events
  (month/week/agenda + quarter tooltip) via shared eventTitle/birthdayIconSvg
- create split-button caret opens a menu: new event / new birthday
- new birthday modal: name + date + "year unknown" + target birthday calendar,
  saved as an all-day FREQ=YEARLY local event with birth_year
- local-calendar modal gains a "birthday calendar" toggle + "notify N days before"
- i18n de/en strings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 22:10:52 +02:00
Scarriffle
d426f8985c style(web): dark-mode the share modal's add-user search + permission select
The user-search input and permission dropdown in the share modal were raw white
browser controls. Style them like the rest of the app (dark bg, border, radius,
focus ring) and give the user checkboxes the primary accent colour. v80.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 13:25:03 +02:00
Scarriffle
ec85a5b5f3 fix(web): show dialogs opened from settings on top of the settings page
The settings modal is a full-screen OPAQUE overlay at z-index 500. Dialogs
opened from within it (share, add-account, color picker) share z-index 500 but
sit earlier in the DOM, so they rendered BEHIND the opaque settings page — the
Share button appeared to "do nothing". Drop the settings page to z-index 400 so
real modals stack above it. v79.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 22:31:03 +02:00
Scarriffle
af64e191ec fix(web): reset checkbox size inside .form-group so the label isn't squeezed
The global ".form-group input" rule (width:100% + padding + border) also hit the
directory-hidden checkbox, blowing it up to a full-width field that pushed the
label text into a narrow wrapping column. Reset the checkbox to a small native
box (16px, no padding/border/background) so the label reads normally beside it.
v78.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 22:23:28 +02:00
Scarriffle
52bc7066db fix(web): settings modal — table crash, tab restore, checkbox layout
Three separate settings bugs (all pre-existing, exposed once the modal actually
opened):

1. renderCalendarTable() referenced a bare `owned` variable (undefined in that
   scope; should be cal.owned) → ReferenceError on the first owned local calendar
   → renderAllAccounts threw → the calendar table never rendered. This was the
   ROOT cause of "settings won't open" (it threw out of openSettingsModal); the
   earlier try/catch only masked it. Fixed to cal.owned.

2. On reload, writeUrlState() (via fetchAndRender) ran before openSettingsModal
   activated the saved tab and wrote the HTML-default (Profile) tab into the URL,
   so every reload landed on Profile. Now the stab is only rewritten once the
   modal is actually shown; otherwise the saved one is preserved.

3. The directory-hidden checkbox label inherited the global ".form-group label"
   uppercase/spaced/12px styling, stretching the text into a broken column. A
   higher-specificity .checkbox-row rule restores normal inline layout.

v77.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 22:16:10 +02:00
Scarriffle
2ae8499247 fix(web): can't edit calendars shared with me; struck-pencil read-only marker
- Sidebar: don't start an inline rename on a calendar I don't own (owned=false)
  — the save would only 403. Colour picker was already gated.
- Sidebar: show a struck-through pencil icon on read-only shared calendars.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 18:38:01 +02:00
Scarriffle
79fdf4f54a feat(sharing): group-shared calendars in every member's sidebar, person share picker, hidden profiles
- Backend: co-member group_visible calendars now surface in /local/calendars
  (owned=false, shared_by=owner, read-only, group_shared) and in the normal
  /caldav/events merge (via readable_local_calendar_ids), deduped against
  direct shares / group calendars so nothing appears twice.
- Backend: new User.directory_hidden — a user can hide from sharing/group
  pickers (/users/directory), while admin user management (/users/) still lists
  them. Migration + profile GET/PUT.
- Backend: /groups/{id} members carry shares_calendar so clients can drop
  phantom rows for members who share nothing.
- Frontend: reachable "Teilen" button on owned local calendars; share modal is
  now a checkbox multi-select of users (checked = shared). Hidden-profile toggle
  in Settings → Profile. Group member filter only lists members who actually
  share (phantom fix). Calendars shared with me moved to a dedicated read-only
  "shared with me" section in the manage table.
- Tests: group_visible propagation, no-share absence, dedup, directory_hidden.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 16:35:11 +02:00
Scarriffle
f662163185 feat(caldav): app-specific passwords so MFA accounts can use CalDAV
CalDAV clients send only user+password over Basic Auth and can't provide a TOTP
code, so account passwords would bypass 2FA. Add revocable app passwords:

- models: AppPassword table (bcrypt hash, label, last_used); auto-created via
  create_all
- profile_router: GET/POST/DELETE /profile/app-passwords (plaintext shown once)
- dav_router: Basic Auth accepts any app password; the account password is
  accepted only when 2FA is disabled
- frontend: "App-Passwörter (CalDAV)" section in the profile modal (create/show-
  once/copy/revoke) + i18n (de/en); login hint now says app password

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 13:15:35 +02:00
Scarriffle
47944ed952 feat: publish local calendars via two-way CalDAV (opt-in, secret token URL)
Backend:
- LocalCalendar gains caldav_published + dav_token + dav_ctag; LocalEvent gains
  etag (migrations in main.py). bump_dav() refreshes ctag/etag on every local
  event write (create/update/delete/import).
- local_router: PUT /calendars/{id} accepts caldav_published (mints/revokes
  token), new POST /calendars/{id}/dav-token/rotate, _cal_dict exposes
  caldav_published + caldav_url.
- New dav_router mounted at root (/dav/{token}/...): a minimal two-way CalDAV
  server (OPTIONS/PROPFIND/REPORT/GET/PUT/DELETE) reusing ical_io build/parse,
  ctag-based change detection. Secret token = auth, no login.

Frontend:
- Settings calendar table: per-local-calendar publish toggle + subscribe URL
  with copy and token-rotate; i18n (de/en) and styling.

Note: reverse proxy must allow WebDAV methods (PROPFIND/REPORT/PUT/DELETE).
VALARM/reminders are not round-tripped via CalDAV.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 10:19:01 +02:00
Scarriffle
f791160d1a fix: mini-cal marks full multi-day span; short week events show title inline
- Mini calendar: mark every day an event spans (not just the start day) so
  multi-day events (Urlaub/Ferien) show a dot across the whole range
- Week view: render short events on one line (time next to title) so the title
  stays visible; drop the location line when there's no room

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 09:42:02 +02:00
Scarriffle
2e76e63ba2 fix: event popup — allow toolbar button clicks and text selection while draggable
- Don't start a header drag when the pointer goes down on a button/link, so
  edit/copy/delete/close work again
- Make the popup body text selectable (user-select: text) for copying

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 12:15:38 +02:00
Scarriffle
be3d4057b3 feat(sidebar): distinct share icon for groupVisible, hide scrollbars
- groupVisible calendars get a share icon instead of the people icon;
  people icon is reserved for actual group calendars
- sidebar scrollbar hidden (scrollbar-width: none + webkit)
- modal-body scrollbar hidden — fixes Impressum scroll indicator

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 21:36:36 +02:00
Scarriffle
34777c78c9 fix(sidebar): min-height approach for action buttons, no overlap or jump
Instead of absolute positioning (which caused icons to overlay text),
use min-height:40px on .cal-item so the row is always tall enough for
28px mini-btns. Buttons stay in the flex flow with display:none when
hidden — no space reserved, no text truncation, no height shift on hover.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 21:24:57 +02:00
Scarriffle
0427e1189d fix(sidebar): absolute-position action buttons to prevent name truncation
Buttons (.cal-item-remove, .cal-item-bell) are now position:absolute so
they never participate in flex layout — names get full available width at
all times. Buttons fade in over the right edge of the item on hover with
no layout shift and no row-height change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 21:18:04 +02:00
Scarriffle
c1fdfe72d0 fix: modal scrollbar clips rounded corners + sidebar hover jump (v56)
- modal-card: overflow:hidden + flex column; modal-body scrolls instead,
  so native scrollbar never overlaps the 20px border-radius corners
- cal-item-remove / cal-item-bell: display:none→flex replaced with
  opacity:0/pointer-events:none→1/auto, eliminating reflow on hover

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 20:58:44 +02:00
Scarriffle
d04e2952cb fix: replace reminders checkbox with bell icon in calendar table (v54)
Bell-on = Benachrichtigungen aktiv, Bell-off (durchgestrichen) = stumm.
Gleiche Logik wie Auge-Icon für Sichtbarkeit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 20:48:12 +02:00
Scarriffle
c5fd5b4e55 fix: calendar table visibility column uses eye icon instead of checkbox (v53)
Replace misleading "Ausgeblendet" checkbox with eye-open/eye-off icon button.
Sichtbar column: eye-open = shown, eye-off = hidden (dimmed). Clicking toggles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 20:45:33 +02:00
Scarriffle
d1c5b66230 feat: web settings restructure + popup drag + calendar management table (v52)
- Remove "Ansicht" tab; move Kalenderansicht to top of Darstellung
- Reorder Darstellung: Kalenderansicht → Sprache → Stundenhöhe → Farben
- Move Standard-Termindauer to Profil tab as contrast-button selector
- Replace per-source account sections in Kalender tab with unified
  calendar management table (Name/Herkunft/Ausgeblendet/Benachrichtigungen/
  Export·Import/Sync/Delete) covering all calendar sources
- Add "Konto hinzufügen" buttons (Lokal/CalDAV/iCal/HA/Google) to Kalender tab
- Popup drag-to-move via pointer capture on .popup-header

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 20:36:09 +02:00
Scarriffle
c515e9d7e1 feat: safe HTML descriptions, custom reminder picker, synced default event duration
- Render event descriptions as sanitized HTML (links/line breaks) instead of
  raw escaped text; no script execution
- Reminder picker: presets + custom number+unit (minutes/hours/days/weeks)
- Grey out + hint the reminder editor when a calendar's notifications are off
  (reminders are kept, just not fired)
- New synced setting default_event_duration_minutes (default 60) for new events

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 10:00:52 +02:00
Scarriffle
e6bc7eab9d Web: replace chevron chars with clip-path pointed bar ends in overflow popup
All-day continuation bars now use CSS clip-path polygon for the tapered
arrow shape; bars stay inset within the popup (no edge bleed). Version v51.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 20:32:29 +02:00
Scarriffle
70aaec3401 Web: enhance overflow popup with styled all-day bars and continuation arrows
All-day events in the "+N weitere" popup now render as colored bars matching
the month-grid style: continues-left/right arrows when the event spans beyond
the selected day. Timed events keep dot+time+title format. Version bump v50.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 20:02:04 +02:00
Scarriffle
900abcdb7a Web: remove version from tab title, fix month event packing, add day overflow popup
- Tab title shows only "Calendarr" (version stays in sidebar/impressum)
- Fix lane assignment in month view: use 2D per-column occupancy grid instead of
  global colEnd tracking; eliminates empty rows caused by non-overlapping events
  being pushed to lower lanes
- "+N weitere" now opens an inline popup listing all events for that day
  (all-day first, then by time); clicking an event opens its detail popup
- Double-click on day cell navigates to day view (was already implemented)
- Remove hardcoded "v18" from login screen impressum button
- Bump version to v49

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 18:06:54 +02:00
Scarriffle
367087450e Web: custom calendar dropdown in the event editor (shows group icon)
A native <select> can't render the group icon SVG, so the calendar picker
is replaced with a styled dropdown: colour dot + group icon + name, grouped
by account/source with a "Groups" section. The native <select> is kept
hidden as the value holder + change-event source, so all existing save and
private/reminder-row logic is unchanged. Click-outside / Escape close it.

version v46 -> v47.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 20:38:47 +02:00
Scarriffle
c684a424eb Web: caret/selection fix, reminder options & labels, group mute, rounded modal
- Stop the blinking text caret / selection on non-editable UI chrome
  (headings, buttons, icons, dropdowns): body is user-select:none, with text
  selection opted back in for inputs/textareas. Felt like an editable field.
- Reminder options trimmed to 5/15/30 min, 1 h, 1 day, 1 week (dropped 10 min,
  2 h, 2 days; added 1 week). Labels now read "5 Minuten vorher", "1 Tag
  vorher", "1 Woche vorher" instead of "vor 5 Min." / "vor 1 Tag(en)".
- Group calendars can now be muted (reminder bell) in the sidebar when owned.
- Event modal corners rounded (20px) to match the pill buttons.
- version v45 -> v46.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 20:32:01 +02:00
Scarriffle
db43bad432 Web: reminders UI, per-calendar reminder toggle, popup/grid polish
- Event popup: new "Reminders" section for local events — show/add/remove
  multiple reminders, prefilled with the global default on new events; sent
  in the local create/update body and synced like any other event field.
- Sidebar calendar list: per-calendar reminder bell toggle (PUTs the new
  reminders_enabled flag); disabled state shown dimmed.
- Date picker: a day click now commits immediately in date-only mode instead
  of requiring an extra "Save" click.
- Start/End: moving the end before the start now shifts the start back
  (mirroring the start handler) instead of showing an error toast.
- Calendar dropdown: group calendars moved under a "Groups" optgroup; dropped
  the 👥 emoji prefix (a native <select> can't render the icon SVG).
- Month grid: selectedDate defaults to today so the highlight no longer
  follows the cells while navigating before any click.
- Today cell tint now derives from --today-color instead of hardcoded blue.
- version v44 -> v45.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 19:33:40 +02:00
Scarriffle
fc00bf9114 feat(web): group members in the sidebar + per-user member colours
Moved the group member filter from a top bar into the left sidebar (a
"Mitglieder" section that replaces the personal calendar list while a group is
active). Each member row has a checkbox (show/hide their events) and a colour
dot that opens the colour picker to recolour that member just for this viewer —
stored per-device in localStorage and applied over the server colour. Bumped v44.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 20:32:45 +02:00
Scarriffle
817ce075d4 feat(web): non-emoji group icons (inline SVG) for consistent cross-platform look
Group icons are semantic keys rendered as inline SVG (mirroring iOS SF Symbols /
Android Material) in the picker, group list and sidebar flags — instead of OS
emoji that vary per platform. Legacy emoji values still render as a fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 20:25:40 +02:00
Scarriffle
12c14e3c02 feat(web): hide individual member calendars in the group view
In the group overlay a per-member filter bar appears under the banner: tap a
member (or the group calendar) to hide/show their events, Outlook-style.
Filtering is client-side by event owner; members + colours load from the group
detail. Bumped version.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 18:16:25 +02:00
Scarriffle
f834ae5773 feat(web): modernize event popup (glass, colour accent, icon rows, animation)
The event detail popup looked plainly "HTML". Redesigned it: translucent
glass surface (backdrop-blur), the event's colour as an accent strip + tinted
header + glowing dot, body rows with subtle leading icons (time/location/notes/
calendar/creator), rounded 16px corners, layered shadow, and a soft scale+fade
entrance (respecting prefers-reduced-motion). Body rows restructured to
icon+text; JS now drives row visibility and sets --ev-color. Bumped to v40.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-01 09:06:09 +02:00
Scarriffle
8d605ab2cd fix: Monatszelle am Monatswechsel nicht mehr vertikal zentriert
Mein voriges flex/align-center hat "1 JUN" in die Mitte der ganzen Zelle
geschoben. Jetzt: Tageszahl bleibt oben links (wie alle Tage), Monatskürzel
sitzt klein/dezent inline daneben (cell-day inline-flex + kleiner Marker).
Version v38.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 19:00:53 +02:00
Scarriffle
b0f1497bc8 fix: Monatsansicht-Layout bei Monatswechsel + Gruppenkalender in Sidebar
- Monatsmarker ("JUN") sitzt jetzt inline neben der Tageszahl ("1 JUN") statt
  darüber -> einheitliche Zeilenhöhe; Termine der Woche rutschen nicht mehr
  nach unten und überlappen nicht mehr mit "+X weitere".
- Gruppenkalender erscheint in "Meine Kalender" (mit 👥-Markierung) und kann
  aus-/eingeblendet werden; Besitzer kann ihn umfärben. Recolor fremder
  Kalender abgefangen (nur Besitzer). Version v36.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 18:45:49 +02:00
Scarriffle
fd7f7ddfe0 feat: Gruppentermin-Button in der Gruppenansicht + Banner in Akzentfarbe
- "+ Gruppentermin"-Button im Gruppenansicht-Banner: oeffnet den Editor mit
  dem Gruppenkalender vorausgewaehlt -> jeder kann direkt eintragen.
- Banner + aktive Gruppe nutzen jetzt die Akzentfarbe (color-mix, Fallback)
  statt Blau. Version v35.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 18:38:35 +02:00
Scarriffle
7429a309c3 feat: wählbares Gruppen-Icon, geteilter Kalender markiert, Ersteller bei Gruppen-Terminen
- Gruppe: wählbares Emoji-Icon (groups.icon-Spalte + PUT /api/groups/{id});
  wird in der Sidebar statt des Zahnrads angezeigt; Verwalten jetzt klares "⋯".
  Gruppe umbenennen möglich (war vorher gesperrt).
- "Meine Kalender": der aktuell für Gruppen sichtbare Kalender wird mit 👥
  gekennzeichnet.
- Gruppenansicht: Gruppenkalender-Termine zeigen, wer sie hinzugefügt hat
  (👥 Vorname: Titel) und sind nach Ersteller eingefärbt; jeder kann weiterhin
  Termine im Gruppenkalender anlegen. Version v34.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 18:34:59 +02:00
Scarriffle
28a7cbe94e fix: kaputtes Plus-Icon + Kalendernamen nicht vorzeitig abschneiden
- Plus-Icon (Kalender/Gruppen hinzufuegen): fehlerhafter SVG-Pfad (v11 statt
  v6) -> korrekter, symmetrischer Plus-Pfad.
- Entfernen/Auge-Button per display:none statt opacity:0 -> reserviert keinen
  Platz mehr; Kalendername nutzt volle Breite und kuerzt erst beim Hover
  (wenn das Auge erscheint). Version v31.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 17:31:39 +02:00
Scarriffle
8d2f487607 feat: flache sortierbare Kalenderliste (Drag&Drop) + Fixes
- Sidebar: eine flache Kalenderliste statt Quellen-Gruppen; Quelle/Konto
  klein-grau inline rechts neben dem Namen; per Drag&Drop sortierbar
  (Reihenfolge pro Geraet in localStorage).
- Gruppenkalender serverseitig auch beim Besitzer als group:true markiert
  -> erscheint nicht mehr in der "Fuer Gruppen sichtbar"-Auswahl und nicht
  in der normalen Kalenderliste (nur unter Gruppen).
- Settings-URL-State: uiSettingsOpen wird beim Init aus der URL gesetzt,
  bevor das erste writeUrlState() es ueberschreibt -> Reload bleibt jetzt
  wirklich in den Einstellungen.
- Auswahl-Markierungen (Mitglieder/Gruppen-Sichtbar) in Akzentfarbe,
  CSS-gezeichnet statt blauer Emoji. Version v28.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 17:23:28 +02:00
Scarriffle
c7185a128e fix: Import-500 bei doppelten UIDs, Picker-UI & Settings-URL-State
- Import: Dedupe doppelter UIDs innerhalb der Datei (Nextcloud exportiert
  wiederkehrende Termine als mehrere VEVENTs gleicher UID) -> kein
  UNIQUE-constraint-500 mehr; Commit abgesichert. Test ergaenzt (15 gruen).
- Picker (Gruppen-Sichtbarkeit + Mitglieder): als <div>-Zeilen statt <label>,
  damit die globale ".form-group label"-Uppercase/Grau-Regel das Layout nicht
  mehr zerschiesst. Saubere .pick-row-Optik (Checkbox/Radio links, Name links).
- Einstellungen haben jetzt eigenen URL-State (#...&settings=1): Reload/Cache-
  leeren bleibt in den Einstellungen statt zur Kalenderansicht zu springen.
- Version v27.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 17:15:17 +02:00
Scarriffle
8abeefcb5a feat: Gruppen-Sichtbarkeit in Einstellungen + "Mit dir geteilt"-Sektion + Import-Fehler
- Einstellungen: neuer "Kalender"-Abschnitt – Radio-Auswahl, welcher eigene
  Kalender fuer Gruppenmitglieder sichtbar ist (group_visible_calendar_id).
- Sidebar: geteilte Kalender in eigener Sektion "Mit dir geteilt" (mit
  Besitzername) statt inline bei "Meine Kalender"; Gruppenkalender dort
  ausgeblendet (erscheinen unter Gruppen).
- Lokale Checkbox tolerant: geteilte/Gruppen-Kalender werden client-seitig
  ein-/ausgeblendet (kein 404-PUT als Nicht-Besitzer).
- Import-Fehler: zeigt HTTP-Status / "Datei zu gross" statt "unbekannter
  Fehler" (z.B. nginx 413). Version v26.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 17:02:03 +02:00
Scarriffle
479da29bc4 fix: Gruppen-Mitgliederliste sauber ausrichten (Checkbox links, Name links)
Eigene .group-member-item-Klasse statt der generischen Picker-Klasse —
behebt versetzte Checkboxen / rechtsbuendige Namen. Version v25.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 16:47:58 +02:00
Scarriffle
e8a13ba33c feat: Gruppen im Web-Frontend + Gruppenkalender in /local/calendars
- Sidebar-Sektion "Gruppen": Liste, Erstellen (Name + Mitglieder-Picker),
  Verwalten (Mitglieder hinzufuegen/entfernen), Loeschen.
- Gruppenansicht: laedt /api/groups/{id}/combined fuer den sichtbaren
  Bereich; Event-Titel werden mit Besitzer-Initialen bzw. Gruppen-Icon
  praefixt; Banner mit "Gruppenansicht verlassen".
- Server: GET /api/local/calendars liefert nun auch Gruppenkalender
  (group:true, read_write) fuer Mitglieder, damit sie im Editor waehlbar
  sind. Test ergaenzt (13 gruen).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 16:37:08 +02:00
Scarriffle
8d2a697f8b feat: Web-Frontend – Sharing, iCal Import/Export, Ersteller & Privat-Flag
- Ersteller-Zeile im Event-Popup (nur wenn Ersteller != aktueller User).
- Privat-Toggle im Event-Editor (nur lokale Kalender) + Sichtbarkeits-
  Auswahl (hidden|busy) in den Einstellungen.
- Lokale Kalender in Settings & Sidebar: Teilen/Importieren/Exportieren-
  Aktionen (nur eigene; geteilte mit "geteilt von"-Badge, kein Loeschen).
- Share-Modal: Benutzerverzeichnis mit Suche, read/read_write, Freigaben
  entfernen.
- api.js: download()-Helper fuer iCal-Export (Blob).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 16:30:47 +02:00
Scarriffle
275e5a2ae0 fix: unaufgeloeste Merge-Konflikt-Marker aus i18n/calendar/week/css entfernt
Beim letzten Beta->Master-Merge sind die <<<<<<< / ======= / >>>>>>>
Marker mit committet worden. Das hat i18n.js mit einem SyntaxError beim
Parsen abgebrochen und damit den gesamten Frontend-Start kaputt gemacht
(=> komplett schwarze Seite, weil applyTheme nie lief).

Acht Bloecke aufgeloest, in allen Faellen die HEAD-Seite behalten
(neue Features: copy-Key, URL-State, all-day-continues-Logik, Event-
Popup-Header). v22 / sw cache v22.
2026-05-19 10:18:49 +02:00