@burdenoff/microfe-timecampus 2026.625.1 → 2026.626.2
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.
- package/dist/timecampus/components/EmptyState.js +14 -0
- package/dist/timecampus/components/EmptyState.js.map +1 -0
- package/dist/timecampus/components/PageLayout.js +23 -15
- package/dist/timecampus/components/PageLayout.js.map +1 -1
- package/dist/timecampus/pages/applets/AppletStorePage.js +33 -30
- package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -1
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js +37 -31
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +48 -44
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +35 -31
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/channels/ChannelsPage.js +27 -24
- package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -1
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js +46 -38
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js +66 -39
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/ReportsPage.js +42 -36
- package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js +2 -0
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +35 -31
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +31 -25
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +43 -35
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScorePage.js +55 -51
- package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +32 -28
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingPage.js +32 -25
- package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +29 -25
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +32 -29
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +29 -25
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +39 -35
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +2 -0
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js +33 -29
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js +122 -104
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingsPage.js +42 -32
- package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js +2 -0
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js +145 -114
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js +49 -45
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectCreatePage.js +28 -24
- package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectDetailPage.js +109 -78
- package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectsPage.js +11 -7
- package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/TasksPage.js +40 -30
- package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +50 -46
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js +18 -14
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamMembersPage.js +41 -35
- package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamPage.js +91 -61
- package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js +40 -36
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +33 -29
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js +17 -13
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateDetailPage.js +67 -49
- package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplatesPage.js +34 -31
- package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeEntriesPage.js +48 -39
- package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeTrackingPage.js +65 -64
- package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimerPage.js +103 -69
- package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +53 -49
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js +65 -47
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetsPage.js +38 -31
- package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +2 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +35 -31
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/workflows/WorkflowsPage.js +43 -33
- package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { IllustratedEmptyState as t } from "@burdenoff/fe-libs/ui";
|
|
3
|
+
//#region src/timecampus/components/EmptyState.tsx
|
|
4
|
+
var n = ({ title: n, description: r, action: i, className: a, illustration: o = "empty-data" }) => /* @__PURE__ */ e(t, {
|
|
5
|
+
illustration: o,
|
|
6
|
+
title: n,
|
|
7
|
+
description: r,
|
|
8
|
+
action: i,
|
|
9
|
+
className: a
|
|
10
|
+
});
|
|
11
|
+
//#endregion
|
|
12
|
+
export { n as EmptyState };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=EmptyState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmptyState.js","names":[],"sources":["../../../src/timecampus/components/EmptyState.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { IllustratedEmptyState } from \"@burdenoff/fe-libs/ui\";\n\ninterface EmptyStateProps {\n /** Retained for backward compatibility; superseded by the illustration. */\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n className?: string;\n /**\n * Illustration name served from the host shell's /illustrations/<name>.webp.\n * Defaults to the neutral \"empty-data\" asset.\n */\n illustration?: string;\n}\n\nexport const EmptyState: FC<EmptyStateProps> = ({\n title,\n description,\n action,\n className,\n illustration = \"empty-data\",\n}) => {\n return (\n <IllustratedEmptyState\n illustration={illustration}\n title={title}\n description={description}\n action={action}\n className={className}\n />\n );\n};\n"],"mappings":";;;AAiBA,IAAa,KAAmC,EAC9C,UACA,gBACA,WACA,cACA,kBAAe,mBAGb,kBAAC,GAAD;CACgB;CACP;CACM;CACL;CACG;CACX,CAAA"}
|
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
import { cn as e } from "../utils/helpers.js";
|
|
2
2
|
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
3
|
-
import { GradientText as r } from "@burdenoff/fe-libs/ui";
|
|
3
|
+
import { GradientText as r, PagePurpose as i } from "@burdenoff/fe-libs/ui";
|
|
4
4
|
//#region src/timecampus/components/PageLayout.tsx
|
|
5
|
-
var
|
|
6
|
-
className: e("min-h-full p-4 sm:p-6",
|
|
5
|
+
var a = ({ title: a, description: o, purpose: s, purposeLearnMoreHref: c, actions: l, children: u, className: d }) => /* @__PURE__ */ n("div", {
|
|
6
|
+
className: e("min-h-full p-4 sm:p-6", d),
|
|
7
7
|
children: [/* @__PURE__ */ n("div", {
|
|
8
|
-
className: "mb-6 flex flex-col gap-4 sm:flex-row sm:items-
|
|
8
|
+
className: "mb-6 flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between",
|
|
9
9
|
children: [/* @__PURE__ */ n("div", {
|
|
10
10
|
className: "min-w-0",
|
|
11
|
-
children: [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
children: [
|
|
12
|
+
/* @__PURE__ */ t("h1", {
|
|
13
|
+
className: "text-2xl font-bold text-text-primary",
|
|
14
|
+
children: /* @__PURE__ */ t(r, { children: a })
|
|
15
|
+
}),
|
|
16
|
+
o && /* @__PURE__ */ t("p", {
|
|
17
|
+
className: "mt-1 text-sm text-text-secondary",
|
|
18
|
+
children: o
|
|
19
|
+
}),
|
|
20
|
+
s && /* @__PURE__ */ t(i, {
|
|
21
|
+
className: "mt-2 max-w-3xl",
|
|
22
|
+
learnMoreHref: c,
|
|
23
|
+
children: s
|
|
24
|
+
})
|
|
25
|
+
]
|
|
26
|
+
}), l && /* @__PURE__ */ t("div", {
|
|
19
27
|
className: "flex flex-wrap items-center gap-2",
|
|
20
|
-
children:
|
|
28
|
+
children: l
|
|
21
29
|
})]
|
|
22
|
-
}),
|
|
30
|
+
}), u]
|
|
23
31
|
});
|
|
24
32
|
//#endregion
|
|
25
|
-
export {
|
|
33
|
+
export { a as PageLayout };
|
|
26
34
|
|
|
27
35
|
//# sourceMappingURL=PageLayout.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/timecampus/components/PageLayout.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { GradientText } from \"@burdenoff/fe-libs/ui\";\nimport { cn } from \"../utils/helpers\";\n\ninterface PageLayoutProps {\n title: string;\n description?: string;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\nexport const PageLayout: FC<PageLayoutProps> = ({\n title,\n description,\n actions,\n children,\n className,\n}) => {\n return (\n <div className={cn(\"min-h-full p-4 sm:p-6\", className)}>\n <div className=\"mb-6 flex flex-col gap-4 sm:flex-row sm:items-
|
|
1
|
+
{"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/timecampus/components/PageLayout.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { GradientText, PagePurpose } from \"@burdenoff/fe-libs/ui\";\nimport { cn } from \"../utils/helpers\";\n\ninterface PageLayoutProps {\n title: string;\n description?: string;\n /**\n * The page's \"story\": a concise, plain-language explanation of what this\n * page/feature is for and the real-world use-case. Rendered just under the\n * header so every page is self-explanatory to a new user. Prefer this over a\n * terse `description` for primary pages.\n */\n purpose?: ReactNode;\n /** Optional \"Learn more\" link rendered inline with the purpose copy. */\n purposeLearnMoreHref?: string;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\nexport const PageLayout: FC<PageLayoutProps> = ({\n title,\n description,\n purpose,\n purposeLearnMoreHref,\n actions,\n children,\n className,\n}) => {\n return (\n <div className={cn(\"min-h-full p-4 sm:p-6\", className)}>\n <div className=\"mb-6 flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>{title}</GradientText>\n </h1>\n {description && (\n <p className=\"mt-1 text-sm text-text-secondary\">{description}</p>\n )}\n {purpose && (\n <PagePurpose\n className=\"mt-2 max-w-3xl\"\n learnMoreHref={purposeLearnMoreHref}\n >\n {purpose}\n </PagePurpose>\n )}\n </div>\n {actions && (\n <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>\n )}\n </div>\n {children}\n </div>\n );\n};\n"],"mappings":";;;;AAqBA,IAAa,KAAmC,EAC9C,UACA,gBACA,YACA,yBACA,YACA,aACA,mBAGE,kBAAC,OAAD;CAAK,WAAW,EAAG,yBAAyB,EAAU;WAAtD,CACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,MAAD;KAAI,WAAU;eACZ,kBAAC,GAAD,EAAA,UAAe,GAAqB,CAAA;KACjC,CAAA;IACJ,KACC,kBAAC,KAAD;KAAG,WAAU;eAAoC;KAAgB,CAAA;IAElE,KACC,kBAAC,GAAD;KACE,WAAU;KACV,eAAe;eAEd;KACW,CAAA;IAEZ;MACL,KACC,kBAAC,OAAD;GAAK,WAAU;aAAqC;GAAc,CAAA,CAEhE;KACL,EACG"}
|
|
@@ -2,66 +2,69 @@ import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
|
2
2
|
import { LoadingSkeleton as t } from "../../components/LoadingSkeleton.js";
|
|
3
3
|
import { useListConfigurationsQuery as n } from "../../../generated/wspace-operations.js";
|
|
4
4
|
import { PageLayout as r } from "../../components/PageLayout.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { EmptyState as i } from "../../components/EmptyState.js";
|
|
6
|
+
import { Download as a, Puzzle as o, Star as s } from "lucide-react";
|
|
7
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
7
8
|
//#region src/timecampus/pages/applets/AppletStorePage.tsx
|
|
8
|
-
function
|
|
9
|
-
let { workspaceId:
|
|
10
|
-
return
|
|
9
|
+
function u() {
|
|
10
|
+
let { workspaceId: u = "" } = e(), { data: d, loading: f, error: p } = n({ variables: { scope: "WORKSPACE" } }), m = (d?.configurations ?? []).filter((e) => e.key.startsWith("applet.store."));
|
|
11
|
+
return f ? /* @__PURE__ */ c(r, {
|
|
11
12
|
title: "Applet Store",
|
|
12
13
|
description: "Browse and install applets to extend TimeCampus",
|
|
13
|
-
children: /* @__PURE__ */
|
|
14
|
+
children: /* @__PURE__ */ c(t, {
|
|
14
15
|
variant: "card",
|
|
15
16
|
count: 6
|
|
16
17
|
})
|
|
17
|
-
}) :
|
|
18
|
+
}) : p ? /* @__PURE__ */ c(r, {
|
|
18
19
|
title: "Applet Store",
|
|
19
20
|
description: "Browse and install applets to extend TimeCampus",
|
|
20
|
-
children: /* @__PURE__ */
|
|
21
|
+
children: /* @__PURE__ */ c("div", {
|
|
21
22
|
className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
|
|
22
23
|
children: "Failed to load applet store data. Please try again later."
|
|
23
24
|
})
|
|
24
|
-
}) : /* @__PURE__ */
|
|
25
|
+
}) : /* @__PURE__ */ c(r, {
|
|
25
26
|
title: "Applet Store",
|
|
26
27
|
description: "Browse and install applets to extend TimeCampus",
|
|
27
|
-
|
|
28
|
+
purpose: "Discover optional add-ons that extend TimeCampus — integrations, extra trackers and views — and install the ones your workflow needs instead of living with a one-size-fits-all setup.",
|
|
29
|
+
children: m.length === 0 ? /* @__PURE__ */ c(i, {
|
|
30
|
+
illustration: "empty-generic",
|
|
31
|
+
title: "No applets available yet",
|
|
32
|
+
description: "Store applets are managed as workspace configurations with the 'applet.store.' key prefix — once published, they'll appear here to browse and install."
|
|
33
|
+
}) : /* @__PURE__ */ c("div", {
|
|
28
34
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
29
|
-
children:
|
|
30
|
-
className: "col-span-full p-8 text-center text-sm text-text-secondary",
|
|
31
|
-
children: "No applets available in the store yet. Store applets are managed as workspace configurations with the \"applet.store.\" key prefix."
|
|
32
|
-
}) : p.map((e) => {
|
|
35
|
+
children: m.map((e) => {
|
|
33
36
|
let t = e.value, n = t.name ?? e.key.replace("applet.store.", ""), r = e.description ?? t.description ?? "";
|
|
34
37
|
t.category;
|
|
35
|
-
let
|
|
36
|
-
return /* @__PURE__ */
|
|
38
|
+
let i = t.rating ?? 0, u = t.downloads ?? 0;
|
|
39
|
+
return /* @__PURE__ */ l("div", {
|
|
37
40
|
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-5 transition-colors hover:bg-bg-sunken/50 cursor-pointer",
|
|
38
|
-
children: [/* @__PURE__ */
|
|
41
|
+
children: [/* @__PURE__ */ l("div", {
|
|
39
42
|
className: "flex items-start gap-3",
|
|
40
|
-
children: [/* @__PURE__ */
|
|
43
|
+
children: [/* @__PURE__ */ c("div", {
|
|
41
44
|
className: "flex h-12 w-12 items-center justify-center rounded-xl bg-action-primary-bg/10",
|
|
42
|
-
children: /* @__PURE__ */
|
|
43
|
-
}), /* @__PURE__ */
|
|
45
|
+
children: /* @__PURE__ */ c(o, { className: "h-6 w-6 text-primary" })
|
|
46
|
+
}), /* @__PURE__ */ l("div", {
|
|
44
47
|
className: "flex-1",
|
|
45
|
-
children: [/* @__PURE__ */
|
|
48
|
+
children: [/* @__PURE__ */ c("p", {
|
|
46
49
|
className: "text-sm font-semibold text-text-primary",
|
|
47
50
|
children: n
|
|
48
|
-
}), /* @__PURE__ */
|
|
51
|
+
}), /* @__PURE__ */ c("p", {
|
|
49
52
|
className: "text-xs text-text-secondary",
|
|
50
53
|
children: r
|
|
51
54
|
})]
|
|
52
55
|
})]
|
|
53
|
-
}), /* @__PURE__ */
|
|
56
|
+
}), /* @__PURE__ */ l("div", {
|
|
54
57
|
className: "mt-3 flex items-center justify-between",
|
|
55
|
-
children: [/* @__PURE__ */
|
|
58
|
+
children: [/* @__PURE__ */ l("div", {
|
|
56
59
|
className: "flex items-center gap-3 text-xs text-text-secondary",
|
|
57
|
-
children: [/* @__PURE__ */
|
|
60
|
+
children: [/* @__PURE__ */ l("div", {
|
|
58
61
|
className: "flex items-center gap-1",
|
|
59
|
-
children: [/* @__PURE__ */ s
|
|
60
|
-
}), /* @__PURE__ */
|
|
62
|
+
children: [/* @__PURE__ */ c(s, { className: "h-3 w-3 fill-amber-400 text-status-warning-text" }), /* @__PURE__ */ c("span", { children: i })]
|
|
63
|
+
}), /* @__PURE__ */ l("div", {
|
|
61
64
|
className: "flex items-center gap-1",
|
|
62
|
-
children: [/* @__PURE__ */
|
|
65
|
+
children: [/* @__PURE__ */ c(a, { className: "h-3 w-3" }), /* @__PURE__ */ c("span", { children: u })]
|
|
63
66
|
})]
|
|
64
|
-
}), /* @__PURE__ */
|
|
67
|
+
}), /* @__PURE__ */ c("button", {
|
|
65
68
|
className: "rounded-md bg-action-primary-bg px-3 py-1 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
66
69
|
children: "Install"
|
|
67
70
|
})]
|
|
@@ -72,6 +75,6 @@ function l() {
|
|
|
72
75
|
});
|
|
73
76
|
}
|
|
74
77
|
//#endregion
|
|
75
|
-
export {
|
|
78
|
+
export { u as AppletStorePage };
|
|
76
79
|
|
|
77
80
|
//# sourceMappingURL=AppletStorePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AppletStorePage.js","names":[],"sources":["../../../../src/timecampus/pages/applets/AppletStorePage.tsx"],"sourcesContent":["import { Puzzle, Star, Download } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function AppletStorePage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as any },\n });\n\n const configurations = data?.configurations ?? [];\n\n // Filter configurations that represent store/available applets (key starts with 'applet.store.')\n const storeApplets = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"applet.store.\"),\n );\n\n if (loading) {\n return (\n <PageLayout\n title=\"Applet Store\"\n description=\"Browse and install applets to extend TimeCampus\"\n >\n <LoadingSkeleton variant=\"card\" count={6} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Applet Store\"\n description=\"Browse and install applets to extend TimeCampus\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load applet store data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Applet Store\"\n description=\"Browse and install applets to extend TimeCampus\"\n
|
|
1
|
+
{"version":3,"file":"AppletStorePage.js","names":[],"sources":["../../../../src/timecampus/pages/applets/AppletStorePage.tsx"],"sourcesContent":["import { Puzzle, Star, Download } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { EmptyState } from \"../../components/EmptyState\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function AppletStorePage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as any },\n });\n\n const configurations = data?.configurations ?? [];\n\n // Filter configurations that represent store/available applets (key starts with 'applet.store.')\n const storeApplets = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"applet.store.\"),\n );\n\n if (loading) {\n return (\n <PageLayout\n title=\"Applet Store\"\n description=\"Browse and install applets to extend TimeCampus\"\n >\n <LoadingSkeleton variant=\"card\" count={6} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Applet Store\"\n description=\"Browse and install applets to extend TimeCampus\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load applet store data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Applet Store\"\n description=\"Browse and install applets to extend TimeCampus\"\n purpose=\"Discover optional add-ons that extend TimeCampus — integrations, extra trackers and views — and install the ones your workflow needs instead of living with a one-size-fits-all setup.\"\n >\n {storeApplets.length === 0 ? (\n <EmptyState\n illustration=\"empty-generic\"\n title=\"No applets available yet\"\n description=\"Store applets are managed as workspace configurations with the 'applet.store.' key prefix — once published, they'll appear here to browse and install.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {storeApplets.map((applet: ConfigurationFieldsFragment) => {\n const val = applet.value as Record<string, unknown>;\n const name =\n (val.name as string) ?? applet.key.replace(\"applet.store.\", \"\");\n const description =\n applet.description ?? (val.description as string) ?? \"\";\n const category = (val.category as string) ?? \"general\";\n const rating = (val.rating as number) ?? 0;\n const downloads = (val.downloads as number) ?? 0;\n\n return (\n <div\n key={applet.id}\n className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-5 transition-colors hover:bg-bg-sunken/50 cursor-pointer\"\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-12 w-12 items-center justify-center rounded-xl bg-action-primary-bg/10\">\n <Puzzle className=\"h-6 w-6 text-primary\" />\n </div>\n <div className=\"flex-1\">\n <p className=\"text-sm font-semibold text-text-primary\">\n {name}\n </p>\n <p className=\"text-xs text-text-secondary\">{description}</p>\n </div>\n </div>\n <div className=\"mt-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-3 text-xs text-text-secondary\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 fill-amber-400 text-status-warning-text\" />\n <span>{rating}</span>\n </div>\n <div className=\"flex items-center gap-1\">\n <Download className=\"h-3 w-3\" />\n <span>{downloads}</span>\n </div>\n </div>\n <button className=\"rounded-md bg-action-primary-bg px-3 py-1 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90\">\n Install\n </button>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAUA,SAAgB,IAAkB;CAChC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA2B,EAC1D,WAAW,EAAE,OAAO,aAAoB,EACzC,CAAC,EAKI,KAHiB,GAAM,kBAAkB,EAAE,EAGb,QAAQ,MAC1C,EAAE,IAAI,WAAW,gBAAgB,CAClC;AA0BD,QAxBI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAoG;GAE7G,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;YAEP,EAAa,WAAW,IACvB,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAa,KAAK,MAAwC;IACzD,IAAM,IAAM,EAAO,OACb,IACH,EAAI,QAAmB,EAAO,IAAI,QAAQ,iBAAiB,GAAG,EAC3D,IACJ,EAAO,eAAgB,EAAI,eAA0B;AACrC,MAAI;IACtB,IAAM,IAAU,EAAI,UAAqB,GACnC,IAAa,EAAI,aAAwB;AAE/C,WACE,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAQ,WAAU,wBAAyB,CAAA;OACvC,CAAA,EACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV;QACC,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAA+B;QAAgB,CAAA,CACxD;SACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,mDAAoD,CAAA,EACpE,kBAAC,QAAD,EAAA,UAAO,GAAc,CAAA,CACjB;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAChC,kBAAC,QAAD,EAAA,UAAO,GAAiB,CAAA,CACpB;UACF;UACN,kBAAC,UAAD;OAAQ,WAAU;iBAAuH;OAEhI,CAAA,CACL;QACF;OA7BC,EAAO,GA6BR;KAER;GACE,CAAA;EAEG,CAAA"}
|
|
@@ -3,72 +3,78 @@ import { getStatusColor as t } from "../../utils/helpers.js";
|
|
|
3
3
|
import { LoadingSkeleton as n } from "../../components/LoadingSkeleton.js";
|
|
4
4
|
import { useListConfigurationsQuery as r } from "../../../generated/wspace-operations.js";
|
|
5
5
|
import { PageLayout as i } from "../../components/PageLayout.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { EmptyState as a } from "../../components/EmptyState.js";
|
|
7
|
+
import { Puzzle as o, Settings as s } from "lucide-react";
|
|
8
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
9
|
+
import { GlassCard as u } from "@burdenoff/fe-libs/ui";
|
|
8
10
|
//#region src/timecampus/pages/applets/InstalledAppletsPage.tsx
|
|
9
|
-
function
|
|
10
|
-
let { workspaceId:
|
|
11
|
-
return
|
|
11
|
+
function d() {
|
|
12
|
+
let { workspaceId: d = "" } = e(), { data: f, loading: p, error: m } = r({ variables: { scope: "WORKSPACE" } }), h = (f?.configurations ?? []).filter((e) => e.key.startsWith("applet.installed."));
|
|
13
|
+
return p ? /* @__PURE__ */ c(i, {
|
|
12
14
|
title: "Installed Applets",
|
|
13
15
|
description: "Manage your installed applets and integrations",
|
|
14
|
-
children: /* @__PURE__ */
|
|
16
|
+
children: /* @__PURE__ */ c(n, {
|
|
15
17
|
variant: "list",
|
|
16
18
|
count: 5
|
|
17
19
|
})
|
|
18
|
-
}) :
|
|
20
|
+
}) : m ? /* @__PURE__ */ c(i, {
|
|
19
21
|
title: "Installed Applets",
|
|
20
22
|
description: "Manage your installed applets and integrations",
|
|
21
|
-
children: /* @__PURE__ */
|
|
23
|
+
children: /* @__PURE__ */ c("div", {
|
|
22
24
|
className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
|
|
23
25
|
children: "Failed to load installed applets. Please try again later."
|
|
24
26
|
})
|
|
25
|
-
}) : /* @__PURE__ */
|
|
27
|
+
}) : /* @__PURE__ */ c(i, {
|
|
26
28
|
title: "Installed Applets",
|
|
27
29
|
description: "Manage your installed applets and integrations",
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
purpose: "See and manage every add-on running in your workspace — enable, configure or update them in one place so you stay in control of how TimeCampus is extended.",
|
|
31
|
+
children: h.length === 0 ? /* @__PURE__ */ c(a, {
|
|
32
|
+
illustration: "empty-generic",
|
|
33
|
+
title: "No applets installed yet",
|
|
34
|
+
description: "Browse the applet store to add integrations and trackers — installed applets are stored as workspace configurations and appear here."
|
|
35
|
+
}) : /* @__PURE__ */ c(u, {
|
|
36
|
+
treatment: "glass",
|
|
37
|
+
glow: !0,
|
|
38
|
+
className: "overflow-hidden",
|
|
39
|
+
children: /* @__PURE__ */ c("div", {
|
|
31
40
|
className: "divide-y divide-border",
|
|
32
|
-
children:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}) : p.map((e) => {
|
|
36
|
-
let n = e.value, r = n.name ?? e.key.replace("applet.installed.", ""), i = n.category ?? "general", l = n.version ?? "1.0.0", u = n.author ?? "Unknown", d = n.isActive ?? !0, f = n.updateAvailable ?? !1;
|
|
37
|
-
return /* @__PURE__ */ c("div", {
|
|
41
|
+
children: h.map((e) => {
|
|
42
|
+
let n = e.value, r = n.name ?? e.key.replace("applet.installed.", ""), i = n.category ?? "general", a = n.version ?? "1.0.0", u = n.author ?? "Unknown", d = n.isActive ?? !0, f = n.updateAvailable ?? !1;
|
|
43
|
+
return /* @__PURE__ */ l("div", {
|
|
38
44
|
className: "flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors",
|
|
39
|
-
children: [/* @__PURE__ */
|
|
45
|
+
children: [/* @__PURE__ */ l("div", {
|
|
40
46
|
className: "flex items-center gap-3",
|
|
41
|
-
children: [/* @__PURE__ */
|
|
47
|
+
children: [/* @__PURE__ */ c("div", {
|
|
42
48
|
className: "flex h-10 w-10 items-center justify-center rounded-lg bg-action-primary-bg/10",
|
|
43
|
-
children: /* @__PURE__ */
|
|
44
|
-
}), /* @__PURE__ */
|
|
49
|
+
children: /* @__PURE__ */ c(o, { className: "h-5 w-5 text-primary" })
|
|
50
|
+
}), /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ l("div", {
|
|
45
51
|
className: "flex items-center gap-2",
|
|
46
|
-
children: [/* @__PURE__ */
|
|
52
|
+
children: [/* @__PURE__ */ c("p", {
|
|
47
53
|
className: "text-sm font-medium text-text-primary",
|
|
48
54
|
children: r
|
|
49
|
-
}), f && /* @__PURE__ */
|
|
55
|
+
}), f && /* @__PURE__ */ c("span", {
|
|
50
56
|
className: "inline-flex rounded-full bg-status-info-bg px-2 py-0.5 text-xs font-medium text-status-info-text",
|
|
51
57
|
children: "Update"
|
|
52
58
|
})]
|
|
53
|
-
}), /* @__PURE__ */
|
|
59
|
+
}), /* @__PURE__ */ l("p", {
|
|
54
60
|
className: "text-xs text-text-secondary",
|
|
55
61
|
children: [
|
|
56
62
|
"v",
|
|
57
|
-
|
|
63
|
+
a,
|
|
58
64
|
" · by ",
|
|
59
65
|
u,
|
|
60
66
|
" · ",
|
|
61
67
|
i
|
|
62
68
|
]
|
|
63
69
|
})] })]
|
|
64
|
-
}), /* @__PURE__ */
|
|
70
|
+
}), /* @__PURE__ */ l("div", {
|
|
65
71
|
className: "flex items-center gap-2",
|
|
66
|
-
children: [/* @__PURE__ */
|
|
72
|
+
children: [/* @__PURE__ */ c("span", {
|
|
67
73
|
className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${t(d ? "active" : "inactive")}`,
|
|
68
74
|
children: d ? "Active" : "Disabled"
|
|
69
|
-
}), /* @__PURE__ */
|
|
75
|
+
}), /* @__PURE__ */ c("button", {
|
|
70
76
|
className: "rounded-md p-1.5 hover:bg-bg-sunken",
|
|
71
|
-
children: /* @__PURE__ */ s
|
|
77
|
+
children: /* @__PURE__ */ c(s, { className: "h-4 w-4 text-text-secondary" })
|
|
72
78
|
})]
|
|
73
79
|
})]
|
|
74
80
|
}, e.id);
|
|
@@ -78,6 +84,6 @@ function l() {
|
|
|
78
84
|
});
|
|
79
85
|
}
|
|
80
86
|
//#endregion
|
|
81
|
-
export {
|
|
87
|
+
export { d as InstalledAppletsPage };
|
|
82
88
|
|
|
83
89
|
//# sourceMappingURL=InstalledAppletsPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstalledAppletsPage.js","names":[],"sources":["../../../../src/timecampus/pages/applets/InstalledAppletsPage.tsx"],"sourcesContent":["import { Puzzle, Settings
|
|
1
|
+
{"version":3,"file":"InstalledAppletsPage.js","names":[],"sources":["../../../../src/timecampus/pages/applets/InstalledAppletsPage.tsx"],"sourcesContent":["import { Puzzle, Settings } from \"lucide-react\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { EmptyState } from \"../../components/EmptyState\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { getStatusColor } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function InstalledAppletsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as any },\n });\n\n const configurations = data?.configurations ?? [];\n\n // Filter configurations that represent installed applets (key starts with 'applet.installed.')\n const applets = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"applet.installed.\"),\n );\n\n if (loading) {\n return (\n <PageLayout\n title=\"Installed Applets\"\n description=\"Manage your installed applets and integrations\"\n >\n <LoadingSkeleton variant=\"list\" count={5} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Installed Applets\"\n description=\"Manage your installed applets and integrations\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load installed applets. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Installed Applets\"\n description=\"Manage your installed applets and integrations\"\n purpose=\"See and manage every add-on running in your workspace — enable, configure or update them in one place so you stay in control of how TimeCampus is extended.\"\n >\n {applets.length === 0 ? (\n <EmptyState\n illustration=\"empty-generic\"\n title=\"No applets installed yet\"\n description=\"Browse the applet store to add integrations and trackers — installed applets are stored as workspace configurations and appear here.\"\n />\n ) : (\n <GlassCard treatment=\"glass\" glow className=\"overflow-hidden\">\n <div className=\"divide-y divide-border\">\n {applets.map((applet: ConfigurationFieldsFragment) => {\n const val = applet.value as Record<string, unknown>;\n const name =\n (val.name as string) ??\n applet.key.replace(\"applet.installed.\", \"\");\n const category = (val.category as string) ?? \"general\";\n const version = (val.version as string) ?? \"1.0.0\";\n const author = (val.author as string) ?? \"Unknown\";\n const isActive = (val.isActive as boolean) ?? true;\n const hasUpdate = (val.updateAvailable as boolean) ?? false;\n\n return (\n <div\n key={applet.id}\n className=\"flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-action-primary-bg/10\">\n <Puzzle className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <div className=\"flex items-center gap-2\">\n <p className=\"text-sm font-medium text-text-primary\">\n {name}\n </p>\n {hasUpdate && (\n <span className=\"inline-flex rounded-full bg-status-info-bg px-2 py-0.5 text-xs font-medium text-status-info-text\">\n Update\n </span>\n )}\n </div>\n <p className=\"text-xs text-text-secondary\">\n v{version} · by {author} · {category}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(isActive ? \"active\" : \"inactive\")}`}\n >\n {isActive ? \"Active\" : \"Disabled\"}\n </span>\n <button className=\"rounded-md p-1.5 hover:bg-bg-sunken\">\n <Settings className=\"h-4 w-4 text-text-secondary\" />\n </button>\n </div>\n </div>\n );\n })}\n </div>\n </GlassCard>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;AAYA,SAAgB,IAAuB;CACrC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA2B,EAC1D,WAAW,EAAE,OAAO,aAAoB,EACzC,CAAC,EAKI,KAHiB,GAAM,kBAAkB,EAAE,EAGlB,QAAQ,MACrC,EAAE,IAAI,WAAW,oBAAoB,CACtC;AA0BD,QAxBI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAoG;GAE7G,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;YAEP,EAAQ,WAAW,IAClB,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,CAAA,GAEF,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAC1C,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAQ,KAAK,MAAwC;KACpD,IAAM,IAAM,EAAO,OACb,IACH,EAAI,QACL,EAAO,IAAI,QAAQ,qBAAqB,GAAG,EACvC,IAAY,EAAI,YAAuB,WACvC,IAAW,EAAI,WAAsB,SACrC,IAAU,EAAI,UAAqB,WACnC,IAAY,EAAI,YAAwB,IACxC,IAAa,EAAI,mBAA+B;AAEtD,YACE,kBAAC,OAAD;MAEE,WAAU;gBAFZ,CAIE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAQ,WAAU,wBAAyB,CAAA;QACvC,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV;SACC,CAAA,EACH,KACC,kBAAC,QAAD;SAAM,WAAU;mBAAmG;SAE5G,CAAA,CAEL;WACN,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAA2C;SACvC;SAAQ;SAAc;SAAO;SAAW;SACxC;UACA,EAAA,CAAA,CACF;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,QAAD;QACE,WAAW,4DAA4D,EAAe,IAAW,WAAW,WAAW;kBAEtH,IAAW,WAAW;QAClB,CAAA,EACP,kBAAC,UAAD;QAAQ,WAAU;kBAChB,kBAAC,GAAD,EAAU,WAAU,+BAAgC,CAAA;QAC7C,CAAA,CACL;SACF;QAjCC,EAAO,GAiCR;MAER;IACE,CAAA;GACI,CAAA;EAEH,CAAA"}
|
|
@@ -4,104 +4,108 @@ import { StatCard as n } from "../../components/StatCard.js";
|
|
|
4
4
|
import { LoadingSkeleton as r } from "../../components/LoadingSkeleton.js";
|
|
5
5
|
import { useGetAppUsageSummaryQuery as i, useListApplicationUsagesQuery as a } from "../../../generated/wspace-operations.js";
|
|
6
6
|
import { PageLayout as o } from "../../components/PageLayout.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { EmptyState as s } from "../../components/EmptyState.js";
|
|
8
|
+
import { Clock as c, Monitor as l } from "lucide-react";
|
|
9
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
9
10
|
//#region src/timecampus/pages/application-usage/ApplicationUsagePage.tsx
|
|
10
|
-
var
|
|
11
|
+
var f = {
|
|
11
12
|
productive: "bg-status-success-bg text-status-success-text",
|
|
12
13
|
neutral: "bg-bg-sunken text-text-secondary",
|
|
13
14
|
communication: "bg-status-info-bg text-status-info-text",
|
|
14
15
|
distracting: "bg-status-error-bg text-status-error-text"
|
|
15
16
|
};
|
|
16
|
-
function
|
|
17
|
-
let { workspaceId:
|
|
17
|
+
function p() {
|
|
18
|
+
let { workspaceId: p = "" } = e(), { data: m, loading: h, error: g } = a({
|
|
18
19
|
variables: { limit: 50 },
|
|
19
|
-
skip: !
|
|
20
|
-
}), { data:
|
|
21
|
-
return
|
|
20
|
+
skip: !p
|
|
21
|
+
}), { data: _, loading: v, error: y } = i({ skip: !p }), b = h || v, x = g || y, S = m?.applicationUsages ?? [], C = _?.appUsageSummary, w = S.reduce((e, t) => e + t.timeSpent, 0), T = S.reduce((e, t) => e + t.switches, 0), E = C?.productivityRatio == null ? "--" : `${Math.round(C.productivityRatio * 100)}%`, D = S.filter((e) => e.timeSpent >= 5400).length;
|
|
22
|
+
return b ? /* @__PURE__ */ u(o, {
|
|
22
23
|
title: "App Usage",
|
|
23
24
|
description: "Track application usage and productivity",
|
|
24
|
-
children: /* @__PURE__ */
|
|
25
|
+
children: /* @__PURE__ */ u(r, {
|
|
25
26
|
variant: "card",
|
|
26
27
|
count: 4
|
|
27
28
|
})
|
|
28
|
-
}) :
|
|
29
|
+
}) : x ? /* @__PURE__ */ u(o, {
|
|
29
30
|
title: "App Usage",
|
|
30
31
|
description: "Track application usage and productivity",
|
|
31
|
-
children: /* @__PURE__ */
|
|
32
|
+
children: /* @__PURE__ */ u("div", {
|
|
32
33
|
className: "rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text",
|
|
33
34
|
children: "Failed to load application usage. Please try again later."
|
|
34
35
|
})
|
|
35
|
-
}) : /* @__PURE__ */
|
|
36
|
+
}) : /* @__PURE__ */ d(o, {
|
|
36
37
|
title: "App Usage",
|
|
37
38
|
description: "Track application usage and productivity",
|
|
38
|
-
|
|
39
|
+
purpose: "See where your screen time actually goes — which apps are productive, how often you context-switch, and how many real focus sessions you get — so you can cut the digital distractions eating your day.",
|
|
40
|
+
children: [/* @__PURE__ */ d("div", {
|
|
39
41
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
|
|
40
42
|
children: [
|
|
41
|
-
/* @__PURE__ */
|
|
43
|
+
/* @__PURE__ */ u(n, {
|
|
44
|
+
featured: !0,
|
|
42
45
|
title: "Total Screen Time",
|
|
43
|
-
value: t(
|
|
44
|
-
icon: /* @__PURE__ */ l
|
|
46
|
+
value: t(w / 3600),
|
|
47
|
+
icon: /* @__PURE__ */ u(l, { className: "h-5 w-5" })
|
|
45
48
|
}),
|
|
46
|
-
/* @__PURE__ */
|
|
49
|
+
/* @__PURE__ */ u(n, {
|
|
47
50
|
title: "Productive Time",
|
|
48
|
-
value:
|
|
49
|
-
trend:
|
|
51
|
+
value: E,
|
|
52
|
+
trend: C?.productivityRatio == null ? void 0 : {
|
|
50
53
|
value: 5,
|
|
51
54
|
label: "vs last week"
|
|
52
55
|
}
|
|
53
56
|
}),
|
|
54
|
-
/* @__PURE__ */
|
|
57
|
+
/* @__PURE__ */ u(n, {
|
|
55
58
|
title: "App Switches",
|
|
56
|
-
value: String(
|
|
57
|
-
description: `Avg. ${
|
|
59
|
+
value: String(T),
|
|
60
|
+
description: `Avg. ${S.length > 0 ? Math.round(T / S.length) : 0}/app`
|
|
58
61
|
}),
|
|
59
|
-
/* @__PURE__ */
|
|
62
|
+
/* @__PURE__ */ u(n, {
|
|
60
63
|
title: "Focus Sessions",
|
|
61
|
-
value: String(
|
|
62
|
-
icon: /* @__PURE__ */
|
|
64
|
+
value: String(D),
|
|
65
|
+
icon: /* @__PURE__ */ u(c, { className: "h-5 w-5" }),
|
|
63
66
|
description: "90+ min each"
|
|
64
67
|
})
|
|
65
68
|
]
|
|
66
|
-
}), /* @__PURE__ */
|
|
69
|
+
}), S.length === 0 ? /* @__PURE__ */ u(s, {
|
|
70
|
+
illustration: "empty-data",
|
|
71
|
+
title: "No application usage data found",
|
|
72
|
+
description: "Once the desktop tracker is active, the apps you use will appear here ranked by time spent."
|
|
73
|
+
}) : /* @__PURE__ */ u("div", {
|
|
67
74
|
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop",
|
|
68
|
-
children: /* @__PURE__ */
|
|
75
|
+
children: /* @__PURE__ */ u("div", {
|
|
69
76
|
className: "divide-y divide-border",
|
|
70
|
-
children:
|
|
71
|
-
className: "p-8 text-center text-sm text-text-secondary",
|
|
72
|
-
children: "No application usage data found."
|
|
73
|
-
}) : x.map((e) => /* @__PURE__ */ u("div", {
|
|
77
|
+
children: S.map((e) => /* @__PURE__ */ d("div", {
|
|
74
78
|
className: "flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors",
|
|
75
|
-
children: [/* @__PURE__ */
|
|
79
|
+
children: [/* @__PURE__ */ d("div", {
|
|
76
80
|
className: "flex items-center gap-3",
|
|
77
|
-
children: [/* @__PURE__ */ l
|
|
81
|
+
children: [/* @__PURE__ */ u(l, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
|
|
78
82
|
className: "text-sm font-medium text-text-primary",
|
|
79
83
|
children: e.applicationName
|
|
80
|
-
}), /* @__PURE__ */
|
|
84
|
+
}), /* @__PURE__ */ d("p", {
|
|
81
85
|
className: "text-xs text-text-secondary",
|
|
82
86
|
children: [e.sessions, " sessions"]
|
|
83
87
|
})] })]
|
|
84
|
-
}), /* @__PURE__ */
|
|
88
|
+
}), /* @__PURE__ */ d("div", {
|
|
85
89
|
className: "flex items-center gap-4",
|
|
86
90
|
children: [
|
|
87
|
-
/* @__PURE__ */
|
|
91
|
+
/* @__PURE__ */ u("div", {
|
|
88
92
|
className: "text-right",
|
|
89
|
-
children: /* @__PURE__ */
|
|
93
|
+
children: /* @__PURE__ */ u("p", {
|
|
90
94
|
className: "text-sm font-mono font-medium text-text-primary",
|
|
91
95
|
children: t(e.timeSpent / 3600)
|
|
92
96
|
})
|
|
93
97
|
}),
|
|
94
|
-
/* @__PURE__ */
|
|
95
|
-
className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${
|
|
98
|
+
/* @__PURE__ */ u("span", {
|
|
99
|
+
className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${f[e.category] || ""}`,
|
|
96
100
|
children: e.category
|
|
97
101
|
}),
|
|
98
|
-
/* @__PURE__ */
|
|
102
|
+
/* @__PURE__ */ u("div", {
|
|
99
103
|
className: "w-16",
|
|
100
|
-
children: /* @__PURE__ */
|
|
104
|
+
children: /* @__PURE__ */ u("div", {
|
|
101
105
|
className: "h-2 rounded-full bg-bg-sunken",
|
|
102
|
-
children: /* @__PURE__ */
|
|
106
|
+
children: /* @__PURE__ */ u("div", {
|
|
103
107
|
className: "h-2 rounded-full bg-action-primary-bg",
|
|
104
|
-
style: { width: `${Math.min(100, Math.round(e.timeSpent / (
|
|
108
|
+
style: { width: `${Math.min(100, Math.round(e.timeSpent / (w || 1) * 100))}%` }
|
|
105
109
|
})
|
|
106
110
|
})
|
|
107
111
|
})
|
|
@@ -113,6 +117,6 @@ function f() {
|
|
|
113
117
|
});
|
|
114
118
|
}
|
|
115
119
|
//#endregion
|
|
116
|
-
export {
|
|
120
|
+
export { p as ApplicationUsagePage };
|
|
117
121
|
|
|
118
122
|
//# sourceMappingURL=ApplicationUsagePage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationUsagePage.js","names":[],"sources":["../../../../src/timecampus/pages/application-usage/ApplicationUsagePage.tsx"],"sourcesContent":["import { Monitor, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours, getStatusColor } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListApplicationUsagesQuery,\n useGetAppUsageSummaryQuery,\n type ApplicationUsageFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst categoryColors: Record<string, string> = {\n productive: \"bg-status-success-bg text-status-success-text\",\n neutral: \"bg-bg-sunken text-text-secondary\",\n communication: \"bg-status-info-bg text-status-info-text\",\n distracting: \"bg-status-error-bg text-status-error-text\",\n};\n\nexport function ApplicationUsagePage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: usagesData,\n loading: usagesLoading,\n error: usagesError,\n } = useListApplicationUsagesQuery({\n variables: { limit: 50 },\n skip: !workspaceId,\n });\n\n const {\n data: summaryData,\n loading: summaryLoading,\n error: summaryError,\n } = useGetAppUsageSummaryQuery({\n skip: !workspaceId,\n });\n\n const loading = usagesLoading || summaryLoading;\n const error = usagesError || summaryError;\n const apps = usagesData?.applicationUsages ?? [];\n const summary = summaryData?.appUsageSummary;\n\n const totalScreenTimeSeconds = apps.reduce(\n (sum: number, app: ApplicationUsageFieldsFragment) => sum + app.timeSpent,\n 0,\n );\n const totalSwitches = apps.reduce(\n (sum: number, app: ApplicationUsageFieldsFragment) => sum + app.switches,\n 0,\n );\n const productiveRatio =\n summary?.productivityRatio != null\n ? `${Math.round(summary.productivityRatio * 100)}%`\n : \"--\";\n\n // Count focus sessions (apps with > 90 min continuous usage)\n const focusSessions = apps.filter(\n (app: ApplicationUsageFieldsFragment) => app.timeSpent >= 5400,\n ).length;\n\n if (loading) {\n return (\n <PageLayout\n title=\"App Usage\"\n description=\"Track application usage and productivity\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"App Usage\"\n description=\"Track application usage and productivity\"\n >\n <div className=\"rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load application usage. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"App Usage\"\n description=\"Track application usage and productivity\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Total Screen Time\"\n value={formatHours(totalScreenTimeSeconds / 3600)}\n icon={<Monitor className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Productive Time\"\n value={productiveRatio}\n trend={\n summary?.productivityRatio != null\n ? { value: 5, label: \"vs last week\" }\n : undefined\n }\n />\n <StatCard\n title=\"App Switches\"\n value={String(totalSwitches)}\n description={`Avg. ${apps.length > 0 ? Math.round(totalSwitches / apps.length) : 0}/app`}\n />\n <StatCard\n title=\"Focus Sessions\"\n value={String(focusSessions)}\n icon={<Clock className=\"h-5 w-5\" />}\n description=\"90+ min each\"\n />\n </div>\n\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop\">\n
|
|
1
|
+
{"version":3,"file":"ApplicationUsagePage.js","names":[],"sources":["../../../../src/timecampus/pages/application-usage/ApplicationUsagePage.tsx"],"sourcesContent":["import { Monitor, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { EmptyState } from \"../../components/EmptyState\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours, getStatusColor } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListApplicationUsagesQuery,\n useGetAppUsageSummaryQuery,\n type ApplicationUsageFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst categoryColors: Record<string, string> = {\n productive: \"bg-status-success-bg text-status-success-text\",\n neutral: \"bg-bg-sunken text-text-secondary\",\n communication: \"bg-status-info-bg text-status-info-text\",\n distracting: \"bg-status-error-bg text-status-error-text\",\n};\n\nexport function ApplicationUsagePage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: usagesData,\n loading: usagesLoading,\n error: usagesError,\n } = useListApplicationUsagesQuery({\n variables: { limit: 50 },\n skip: !workspaceId,\n });\n\n const {\n data: summaryData,\n loading: summaryLoading,\n error: summaryError,\n } = useGetAppUsageSummaryQuery({\n skip: !workspaceId,\n });\n\n const loading = usagesLoading || summaryLoading;\n const error = usagesError || summaryError;\n const apps = usagesData?.applicationUsages ?? [];\n const summary = summaryData?.appUsageSummary;\n\n const totalScreenTimeSeconds = apps.reduce(\n (sum: number, app: ApplicationUsageFieldsFragment) => sum + app.timeSpent,\n 0,\n );\n const totalSwitches = apps.reduce(\n (sum: number, app: ApplicationUsageFieldsFragment) => sum + app.switches,\n 0,\n );\n const productiveRatio =\n summary?.productivityRatio != null\n ? `${Math.round(summary.productivityRatio * 100)}%`\n : \"--\";\n\n // Count focus sessions (apps with > 90 min continuous usage)\n const focusSessions = apps.filter(\n (app: ApplicationUsageFieldsFragment) => app.timeSpent >= 5400,\n ).length;\n\n if (loading) {\n return (\n <PageLayout\n title=\"App Usage\"\n description=\"Track application usage and productivity\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"App Usage\"\n description=\"Track application usage and productivity\"\n >\n <div className=\"rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load application usage. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"App Usage\"\n description=\"Track application usage and productivity\"\n purpose=\"See where your screen time actually goes — which apps are productive, how often you context-switch, and how many real focus sessions you get — so you can cut the digital distractions eating your day.\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n featured\n title=\"Total Screen Time\"\n value={formatHours(totalScreenTimeSeconds / 3600)}\n icon={<Monitor className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Productive Time\"\n value={productiveRatio}\n trend={\n summary?.productivityRatio != null\n ? { value: 5, label: \"vs last week\" }\n : undefined\n }\n />\n <StatCard\n title=\"App Switches\"\n value={String(totalSwitches)}\n description={`Avg. ${apps.length > 0 ? Math.round(totalSwitches / apps.length) : 0}/app`}\n />\n <StatCard\n title=\"Focus Sessions\"\n value={String(focusSessions)}\n icon={<Clock className=\"h-5 w-5\" />}\n description=\"90+ min each\"\n />\n </div>\n\n {apps.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No application usage data found\"\n description=\"Once the desktop tracker is active, the apps you use will appear here ranked by time spent.\"\n />\n ) : (\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop\">\n <div className=\"divide-y divide-border\">\n {apps.map((app: ApplicationUsageFieldsFragment) => (\n <div\n key={app.id}\n className=\"flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <Monitor className=\"h-5 w-5 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {app.applicationName}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {app.sessions} sessions\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"text-right\">\n <p className=\"text-sm font-mono font-medium text-text-primary\">\n {formatHours(app.timeSpent / 3600)}\n </p>\n </div>\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${categoryColors[app.category] || \"\"}`}\n >\n {app.category}\n </span>\n <div className=\"w-16\">\n <div className=\"h-2 rounded-full bg-bg-sunken\">\n <div\n className=\"h-2 rounded-full bg-action-primary-bg\"\n style={{\n width: `${Math.min(100, Math.round((app.timeSpent / (totalScreenTimeSeconds || 1)) * 100))}%`,\n }}\n />\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;AAaA,IAAM,IAAyC;CAC7C,YAAY;CACZ,SAAS;CACT,eAAe;CACf,aAAa;CACd;AAED,SAAgB,IAAuB;CACrC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,EAA8B;EAChC,WAAW,EAAE,OAAO,IAAI;EACxB,MAAM,CAAC;EACR,CAAC,EAEI,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,EAA2B,EAC7B,MAAM,CAAC,GACR,CAAC,EAEI,IAAU,KAAiB,GAC3B,IAAQ,KAAe,GACvB,IAAO,GAAY,qBAAqB,EAAE,EAC1C,IAAU,GAAa,iBAEvB,IAAyB,EAAK,QACjC,GAAa,MAAwC,IAAM,EAAI,WAChE,EACD,EACK,IAAgB,EAAK,QACxB,GAAa,MAAwC,IAAM,EAAI,UAChE,EACD,EACK,IACJ,GAAS,qBAAqB,OAE1B,OADA,GAAG,KAAK,MAAM,EAAQ,oBAAoB,IAAI,CAAC,IAI/C,IAAgB,EAAK,QACxB,MAAwC,EAAI,aAAa,KAC3D,CAAC;AA0BF,QAxBI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA2G;GAEpH,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;YAHV,CAKE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,UAAA;KACA,OAAM;KACN,OAAO,EAAY,IAAyB,KAAK;KACjD,MAAM,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA;KACrC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,OACE,GAAS,qBAAqB,OAE1B,KAAA,IADA;MAAE,OAAO;MAAG,OAAO;MAAgB;KAGzC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,EAAc;KAC5B,aAAa,QAAQ,EAAK,SAAS,IAAI,KAAK,MAAM,IAAgB,EAAK,OAAO,GAAG,EAAE;KACnF,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,EAAc;KAC5B,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,aAAY;KACZ,CAAA;IACE;MAEL,EAAK,WAAW,IACf,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAK,KAAK,MACT,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAS,WAAU,+BAAgC,CAAA,EACnD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAI;OACH,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAb,CACG,EAAI,UAAS,YACZ;SACA,EAAA,CAAA,CACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAY,EAAI,YAAY,KAAK;SAChC,CAAA;QACA,CAAA;OACN,kBAAC,QAAD;QACE,WAAW,4DAA4D,EAAe,EAAI,aAAa;kBAEtG,EAAI;QACA,CAAA;OACP,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,OAAD;UACE,WAAU;UACV,OAAO,EACL,OAAO,GAAG,KAAK,IAAI,KAAK,KAAK,MAAO,EAAI,aAAa,KAA0B,KAAM,IAAI,CAAC,CAAC,IAC5F;UACD,CAAA;SACE,CAAA;QACF,CAAA;OACF;QACF;OApCC,EAAI,GAoCL,CACN;IACE,CAAA;GACF,CAAA,CAEG"}
|