@remit/web-client 0.0.238 → 0.0.239

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,6 +25,7 @@ import { Route as SettingsIndexRouteImport } from './routes/settings/index'
25
25
  import { Route as SettingsAccountsRouteImport } from './routes/settings/accounts'
26
26
  import { Route as SettingsAdvancedRouteImport } from './routes/settings/advanced'
27
27
  import { Route as SettingsAppearanceRouteImport } from './routes/settings/appearance'
28
+ import { Route as SettingsCalendarsRouteImport } from './routes/settings/calendars'
28
29
  import { Route as SettingsFiltersRouteImport } from './routes/settings/filters'
29
30
  import { Route as SettingsFoldersRouteImport } from './routes/settings/folders'
30
31
  import { Route as SettingsLabelsRouteImport } from './routes/settings/labels'
@@ -138,6 +139,11 @@ const SettingsAppearanceRoute = SettingsAppearanceRouteImport.update({
138
139
  path: '/appearance',
139
140
  getParentRoute: () => SettingsRoute,
140
141
  } as any)
142
+ const SettingsCalendarsRoute = SettingsCalendarsRouteImport.update({
143
+ id: '/calendars',
144
+ path: '/calendars',
145
+ getParentRoute: () => SettingsRoute,
146
+ } as any)
141
147
  const SettingsFiltersRoute = SettingsFiltersRouteImport.update({
142
148
  id: '/filters',
143
149
  path: '/filters',
@@ -335,6 +341,7 @@ export interface FileRoutesByFullPath {
335
341
  '/settings/accounts': typeof SettingsAccountsRoute
336
342
  '/settings/advanced': typeof SettingsAdvancedRoute
337
343
  '/settings/appearance': typeof SettingsAppearanceRoute
344
+ '/settings/calendars': typeof SettingsCalendarsRoute
338
345
  '/settings/filters': typeof SettingsFiltersRoute
339
346
  '/settings/folders': typeof SettingsFoldersRoute
340
347
  '/settings/labels': typeof SettingsLabelsRoute
@@ -378,6 +385,7 @@ export interface FileRoutesByTo {
378
385
  '/settings/accounts': typeof SettingsAccountsRoute
379
386
  '/settings/advanced': typeof SettingsAdvancedRoute
380
387
  '/settings/appearance': typeof SettingsAppearanceRoute
388
+ '/settings/calendars': typeof SettingsCalendarsRoute
381
389
  '/settings/filters': typeof SettingsFiltersRoute
382
390
  '/settings/folders': typeof SettingsFoldersRoute
383
391
  '/settings/labels': typeof SettingsLabelsRoute
@@ -424,6 +432,7 @@ export interface FileRoutesById {
424
432
  '/settings/accounts': typeof SettingsAccountsRoute
425
433
  '/settings/advanced': typeof SettingsAdvancedRoute
426
434
  '/settings/appearance': typeof SettingsAppearanceRoute
435
+ '/settings/calendars': typeof SettingsCalendarsRoute
427
436
  '/settings/filters': typeof SettingsFiltersRoute
428
437
  '/settings/folders': typeof SettingsFoldersRoute
429
438
  '/settings/labels': typeof SettingsLabelsRoute
@@ -476,6 +485,7 @@ export interface FileRouteTypes {
476
485
  | '/settings/accounts'
477
486
  | '/settings/advanced'
478
487
  | '/settings/appearance'
488
+ | '/settings/calendars'
479
489
  | '/settings/filters'
480
490
  | '/settings/folders'
481
491
  | '/settings/labels'
@@ -519,6 +529,7 @@ export interface FileRouteTypes {
519
529
  | '/settings/accounts'
520
530
  | '/settings/advanced'
521
531
  | '/settings/appearance'
532
+ | '/settings/calendars'
522
533
  | '/settings/filters'
523
534
  | '/settings/folders'
524
535
  | '/settings/labels'
@@ -564,6 +575,7 @@ export interface FileRouteTypes {
564
575
  | '/settings/accounts'
565
576
  | '/settings/advanced'
566
577
  | '/settings/appearance'
578
+ | '/settings/calendars'
567
579
  | '/settings/filters'
568
580
  | '/settings/folders'
569
581
  | '/settings/labels'
@@ -724,6 +736,13 @@ declare module '@tanstack/react-router' {
724
736
  preLoaderRoute: typeof SettingsAppearanceRouteImport
725
737
  parentRoute: typeof SettingsRoute
726
738
  }
739
+ '/settings/calendars': {
740
+ id: '/settings/calendars'
741
+ path: '/calendars'
742
+ fullPath: '/settings/calendars'
743
+ preLoaderRoute: typeof SettingsCalendarsRouteImport
744
+ parentRoute: typeof SettingsRoute
745
+ }
727
746
  '/settings/filters': {
728
747
  id: '/settings/filters'
729
748
  path: '/filters'
@@ -1177,6 +1196,7 @@ interface SettingsRouteChildren {
1177
1196
  SettingsAccountsRoute: typeof SettingsAccountsRoute
1178
1197
  SettingsAdvancedRoute: typeof SettingsAdvancedRoute
1179
1198
  SettingsAppearanceRoute: typeof SettingsAppearanceRoute
1199
+ SettingsCalendarsRoute: typeof SettingsCalendarsRoute
1180
1200
  SettingsFiltersRoute: typeof SettingsFiltersRoute
1181
1201
  SettingsFoldersRoute: typeof SettingsFoldersRoute
1182
1202
  SettingsLabelsRoute: typeof SettingsLabelsRoute
@@ -1189,6 +1209,7 @@ const SettingsRouteChildren: SettingsRouteChildren = {
1189
1209
  SettingsAccountsRoute: SettingsAccountsRoute,
1190
1210
  SettingsAdvancedRoute: SettingsAdvancedRoute,
1191
1211
  SettingsAppearanceRoute: SettingsAppearanceRoute,
1212
+ SettingsCalendarsRoute: SettingsCalendarsRoute,
1192
1213
  SettingsFiltersRoute: SettingsFiltersRoute,
1193
1214
  SettingsFoldersRoute: SettingsFoldersRoute,
1194
1215
  SettingsLabelsRoute: SettingsLabelsRoute,
@@ -0,0 +1,73 @@
1
+ import { SettingsShell } from "@remit/ui";
2
+ import { createFileRoute, useNavigate } from "@tanstack/react-router";
3
+ import { useState } from "react";
4
+ import { CalendarFeedPanel } from "@/components/settings/CalendarFeedPanel";
5
+ import { useCalendars } from "@/hooks/calendar/useCalendars";
6
+ import { SETTINGS_ID_TO_PATH, SETTINGS_NAV_ITEMS } from "@/routes/settings";
7
+
8
+ export const Route = createFileRoute("/settings/calendars")({
9
+ component: CalendarsSettings,
10
+ });
11
+
12
+ const calendarsHelp = (
13
+ <div className="space-y-3">
14
+ <p>
15
+ A subscription address lets Apple Calendar, Google Calendar, Outlook and
16
+ Thunderbird show a calendar from here, read-only and kept up to date.
17
+ </p>
18
+ <p>
19
+ Those clients never sign in, so the address itself is the credential.
20
+ Anyone who has it can read the calendar; nobody who has it can change
21
+ anything.
22
+ </p>
23
+ <p>
24
+ Only a hash of the address is stored, so it is shown once and cannot be
25
+ looked up later. Replacing it breaks every subscription built on the old
26
+ one, which is how a shared address is taken back.
27
+ </p>
28
+ </div>
29
+ );
30
+
31
+ function CalendarsSettings() {
32
+ const navigate = useNavigate();
33
+ const [helpOpen, setHelpOpen] = useState(true);
34
+ const { calendars, isLoading } = useCalendars();
35
+
36
+ return (
37
+ <SettingsShell
38
+ items={SETTINGS_NAV_ITEMS}
39
+ activeId="calendars"
40
+ title="Calendars"
41
+ description="Share a calendar with any client that can subscribe to a URL."
42
+ help={calendarsHelp}
43
+ helpOpen={helpOpen}
44
+ onToggleHelp={() => setHelpOpen((open) => !open)}
45
+ onSelect={(id) => {
46
+ const path = SETTINGS_ID_TO_PATH[id];
47
+ if (path) void navigate({ to: path });
48
+ }}
49
+ onBackToMail={() => void navigate({ to: "/mail" })}
50
+ >
51
+ {isLoading ? (
52
+ // biome-ignore lint/a11y/useAriaPropsSupportedByRole: aria-label on a loading skeleton is what assistive tech has to go on
53
+ <div
54
+ className="h-24 animate-pulse rounded-sm border border-line bg-surface"
55
+ aria-busy="true"
56
+ aria-label="Loading calendars"
57
+ />
58
+ ) : calendars.length === 0 ? (
59
+ <p className="py-12 text-sm text-fg-muted">No calendars yet.</p>
60
+ ) : (
61
+ <div className="space-y-4">
62
+ {calendars.map((calendar) => (
63
+ <CalendarFeedPanel
64
+ key={calendar.id}
65
+ calendarId={calendar.id}
66
+ calendarName={calendar.name}
67
+ />
68
+ ))}
69
+ </div>
70
+ )}
71
+ </SettingsShell>
72
+ );
73
+ }
@@ -10,7 +10,15 @@
10
10
  */
11
11
  import type { SettingsNavItem } from "@remit/ui";
12
12
  import { createFileRoute, Outlet } from "@tanstack/react-router";
13
- import { Filter, FolderTree, Inbox, Palette, Tag, Users } from "lucide-react";
13
+ import {
14
+ CalendarDays,
15
+ Filter,
16
+ FolderTree,
17
+ Inbox,
18
+ Palette,
19
+ Tag,
20
+ Users,
21
+ } from "lucide-react";
14
22
  import { AdvancedNavIcon } from "@/components/settings/AdvancedNavIcon";
15
23
 
16
24
  /* ------------------------------------------------------------------ */
@@ -39,6 +47,11 @@ export const SETTINGS_NAV_ITEMS: SettingsNavItem[] = [
39
47
  label: "Labels",
40
48
  icon: <Tag className="size-4" />,
41
49
  },
50
+ {
51
+ id: "calendars",
52
+ label: "Calendars",
53
+ icon: <CalendarDays className="size-4" />,
54
+ },
42
55
  {
43
56
  id: "appearance",
44
57
  label: "Appearance",
@@ -53,6 +66,7 @@ export const SETTINGS_ID_TO_PATH: Record<string, string> = {
53
66
  folders: "/settings/folders",
54
67
  filters: "/settings/filters",
55
68
  labels: "/settings/labels",
69
+ calendars: "/settings/calendars",
56
70
  appearance: "/settings/appearance",
57
71
  advanced: "/settings/advanced",
58
72
  };