@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateApplicationPage.js","names":[],"sources":["../../../../src/timecampus/pages/templates/TemplateApplicationPage.tsx"],"sourcesContent":["import { useParams } from \"react-router-dom\";\nimport { Sparkles, CheckCircle, Loader2 } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useGetConfigurationQuery } from \"@/generated/wspace-operations\";\n\nexport function TemplateApplicationPage() {\n const { applicationId } = useParams<{ applicationId: string }>();\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationQuery({\n variables: { id: applicationId ?? \"\" },\n skip: !applicationId,\n });\n\n const config = data?.configuration;\n const val = (config?.value as Record<string, unknown>) ?? {};\n\n // Application steps from configuration or defaults\n const configuredSteps = val.applicationSteps as\n | Array<{ label: string; status: string }>\n | undefined;\n const steps = configuredSteps ?? [\n { label: \"Project structure\", status: \"pending\" },\n { label: \"Time categories\", status: \"pending\" },\n { label: \"Team roles\", status: \"pending\" },\n { label: \"Dashboard widgets\", status: \"pending\" },\n { label: \"Workflows\", status: \"pending\" },\n ];\n\n if (loading) {\n return (\n <PageLayout title=\"Applying Template\" description=\"Loading...\">\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Applying Template\"\n description={`Application ID: ${applicationId}`}\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 template application data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Applying Template\"\n description={`Application ID: ${applicationId}`}\n >\n <div className=\"mx-auto max-w-lg\">\n <
|
|
1
|
+
{"version":3,"file":"TemplateApplicationPage.js","names":[],"sources":["../../../../src/timecampus/pages/templates/TemplateApplicationPage.tsx"],"sourcesContent":["import { useParams } from \"react-router-dom\";\nimport { Sparkles, CheckCircle, Loader2 } from \"lucide-react\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useGetConfigurationQuery } from \"@/generated/wspace-operations\";\n\nexport function TemplateApplicationPage() {\n const { applicationId } = useParams<{ applicationId: string }>();\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationQuery({\n variables: { id: applicationId ?? \"\" },\n skip: !applicationId,\n });\n\n const config = data?.configuration;\n const val = (config?.value as Record<string, unknown>) ?? {};\n\n // Application steps from configuration or defaults\n const configuredSteps = val.applicationSteps as\n | Array<{ label: string; status: string }>\n | undefined;\n const steps = configuredSteps ?? [\n { label: \"Project structure\", status: \"pending\" },\n { label: \"Time categories\", status: \"pending\" },\n { label: \"Team roles\", status: \"pending\" },\n { label: \"Dashboard widgets\", status: \"pending\" },\n { label: \"Workflows\", status: \"pending\" },\n ];\n\n if (loading) {\n return (\n <PageLayout title=\"Applying Template\" description=\"Loading...\">\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Applying Template\"\n description={`Application ID: ${applicationId}`}\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 template application data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Applying Template\"\n description={`Application ID: ${applicationId}`}\n purpose=\"Watch your chosen template build out your workspace step by step — projects, categories, roles, widgets and workflows — so you can see exactly what's being configured as it happens.\"\n >\n <div className=\"mx-auto max-w-lg\">\n <GlassCard treatment=\"glass\" glow className=\"p-6 text-center\">\n <div className=\"flex h-16 w-16 mx-auto items-center justify-center rounded-full bg-action-primary-bg/10\">\n <Sparkles className=\"h-8 w-8 text-primary\" />\n </div>\n <h2 className=\"mt-4 text-lg font-semibold text-text-primary\">\n Setting up your workspace\n </h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n Applying the template configuration...\n </p>\n\n <div className=\"mt-6 space-y-3 text-left\">\n {steps.map((step) => (\n <div\n key={step.label}\n className=\"flex items-center gap-3 rounded-lg border border-border-subtle p-3\"\n >\n {step.status === \"completed\" ? (\n <CheckCircle className=\"h-5 w-5 text-status-success-text\" />\n ) : step.status === \"in-progress\" ? (\n <Loader2 className=\"h-5 w-5 text-primary animate-spin\" />\n ) : (\n <div className=\"h-5 w-5 rounded-full border-2 border-muted\" />\n )}\n <span\n className={`text-sm ${step.status === \"completed\" ? \"text-text-secondary\" : \"text-text-primary\"}`}\n >\n {step.label}\n </span>\n </div>\n ))}\n </div>\n </GlassCard>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,IAA0B;CACxC,IAAM,EAAE,qBAAkB,GAAsC,EAC1D,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAAyB;EACxD,WAAW,EAAE,IAAI,KAAiB,IAAI;EACtC,MAAM,CAAC;EACR,CAAC,EASI,KAPS,GAAM,eACA,SAAqC,EAAE,EAGhC,oBAGK;EAC/B;GAAE,OAAO;GAAqB,QAAQ;GAAW;EACjD;GAAE,OAAO;GAAmB,QAAQ;GAAW;EAC/C;GAAE,OAAO;GAAc,QAAQ;GAAW;EAC1C;GAAE,OAAO;GAAqB,QAAQ;GAAW;EACjD;GAAE,OAAO;GAAa,QAAQ;GAAW;EAC1C;AAuBD,QArBI,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAoB,aAAY;YAChD,kBAAC,GAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAa,mBAAmB;YAEhC,kBAAC,OAAD;GAAK,WAAU;aAAoG;GAE7G,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAa,mBAAmB;EAChC,SAAQ;YAER,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD;IAAW,WAAU;IAAQ,MAAA;IAAK,WAAU;cAA5C;KACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAU,WAAU,wBAAyB,CAAA;MACzC,CAAA;KACN,kBAAC,MAAD;MAAI,WAAU;gBAA+C;MAExD,CAAA;KACL,kBAAC,KAAD;MAAG,WAAU;gBAAmC;MAE5C,CAAA;KAEJ,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAM,KAAK,MACV,kBAAC,OAAD;OAEE,WAAU;iBAFZ,CAIG,EAAK,WAAW,cACf,kBAAC,GAAD,EAAa,WAAU,oCAAqC,CAAA,GAC1D,EAAK,WAAW,gBAClB,kBAAC,GAAD,EAAS,WAAU,qCAAsC,CAAA,GAEzD,kBAAC,OAAD,EAAK,WAAU,8CAA+C,CAAA,EAEhE,kBAAC,QAAD;QACE,WAAW,WAAW,EAAK,WAAW,cAAc,wBAAwB;kBAE3E,EAAK;QACD,CAAA,CACH;SAfC,EAAK,MAeN,CACN;MACE,CAAA;KACI;;GACR,CAAA;EACK,CAAA"}
|
|
@@ -1,98 +1,116 @@
|
|
|
1
|
-
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
|
-
import { LoadingSkeleton as
|
|
3
|
-
import { useGetConfigurationQuery as
|
|
4
|
-
import { PageLayout as
|
|
5
|
-
import { ArrowLeft as
|
|
6
|
-
import { useParams as
|
|
7
|
-
import { jsx as
|
|
1
|
+
import { useTimeCampus as e, useTimeCampusNavigate as t } from "../../providers/TimeCampusProvider.js";
|
|
2
|
+
import { LoadingSkeleton as n } from "../../components/LoadingSkeleton.js";
|
|
3
|
+
import { useGetConfigurationQuery as r } from "../../../generated/wspace-operations.js";
|
|
4
|
+
import { PageLayout as i } from "../../components/PageLayout.js";
|
|
5
|
+
import { ArrowLeft as a, CheckCircle as o, Sparkles as s, Star as c, Users as l } from "lucide-react";
|
|
6
|
+
import { useParams as u } from "react-router-dom";
|
|
7
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
8
|
+
import { GlassCard as p, NextSteps as m } from "@burdenoff/fe-libs/ui";
|
|
8
9
|
//#region src/timecampus/pages/templates/TemplateDetailPage.tsx
|
|
9
|
-
function
|
|
10
|
-
let { id:
|
|
11
|
-
variables: { id:
|
|
12
|
-
skip: !
|
|
13
|
-
}),
|
|
14
|
-
return
|
|
10
|
+
function h() {
|
|
11
|
+
let { id: h } = u(), { workspaceId: g = "" } = e(), _ = t(), { data: v, loading: y, error: b } = r({
|
|
12
|
+
variables: { id: h ?? "" },
|
|
13
|
+
skip: !h
|
|
14
|
+
}), x = v?.configuration, S = x?.value ?? {}, C = S.name ?? x?.key?.replace("template.", "") ?? "Template", w = x?.description ?? S.description ?? "A pre-built workspace template for time tracking workflows.", T = S.rating ?? 0, E = S.teamSize ?? "-", D = S.features ?? [];
|
|
15
|
+
return y ? /* @__PURE__ */ d(i, {
|
|
15
16
|
title: "Template Details",
|
|
16
17
|
description: "Loading...",
|
|
17
|
-
children: /* @__PURE__ */
|
|
18
|
-
}) :
|
|
18
|
+
children: /* @__PURE__ */ d(n, { variant: "detail" })
|
|
19
|
+
}) : b || !x ? /* @__PURE__ */ d(i, {
|
|
19
20
|
title: "Template Details",
|
|
20
|
-
description: `Template ID: ${
|
|
21
|
-
actions: /* @__PURE__ */
|
|
21
|
+
description: `Template ID: ${h}`,
|
|
22
|
+
actions: /* @__PURE__ */ f("button", {
|
|
22
23
|
className: "inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
|
|
23
|
-
children: [/* @__PURE__ */
|
|
24
|
+
children: [/* @__PURE__ */ d(a, { className: "h-4 w-4" }), "Back to Templates"]
|
|
24
25
|
}),
|
|
25
|
-
children: /* @__PURE__ */
|
|
26
|
+
children: /* @__PURE__ */ d("div", {
|
|
26
27
|
className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
|
|
27
|
-
children:
|
|
28
|
+
children: b ? "Failed to load template details. Please try again later." : "Template configuration not found."
|
|
28
29
|
})
|
|
29
|
-
}) : /* @__PURE__ */
|
|
30
|
+
}) : /* @__PURE__ */ d(i, {
|
|
30
31
|
title: "Template Details",
|
|
31
|
-
description: `Template ID: ${
|
|
32
|
-
|
|
32
|
+
description: `Template ID: ${h}`,
|
|
33
|
+
purpose: "Review exactly what this template sets up — its features and who it's built for — before you apply it, so you know what will land in your workspace and whether it fits how your team works.",
|
|
34
|
+
actions: /* @__PURE__ */ f("button", {
|
|
33
35
|
className: "inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
|
|
34
|
-
children: [/* @__PURE__ */
|
|
36
|
+
children: [/* @__PURE__ */ d(a, { className: "h-4 w-4" }), "Back to Templates"]
|
|
35
37
|
}),
|
|
36
|
-
children: /* @__PURE__ */
|
|
38
|
+
children: /* @__PURE__ */ f("div", {
|
|
37
39
|
className: "mx-auto max-w-2xl",
|
|
38
|
-
children: /* @__PURE__ */ d(
|
|
39
|
-
|
|
40
|
+
children: [/* @__PURE__ */ d(m, {
|
|
41
|
+
storageKey: "timecampus-template-detail",
|
|
42
|
+
className: "mb-6",
|
|
43
|
+
steps: [{
|
|
44
|
+
id: "apply",
|
|
45
|
+
label: "Apply this template",
|
|
46
|
+
description: "Set up your workspace with this configuration.",
|
|
47
|
+
onClick: () => {}
|
|
48
|
+
}, {
|
|
49
|
+
id: "browse",
|
|
50
|
+
label: "Browse other templates",
|
|
51
|
+
description: "Compare with templates for other workflows.",
|
|
52
|
+
onClick: () => _("/templates")
|
|
53
|
+
}]
|
|
54
|
+
}), /* @__PURE__ */ f(p, {
|
|
55
|
+
treatment: "glass",
|
|
56
|
+
glow: !0,
|
|
57
|
+
className: "p-6",
|
|
40
58
|
children: [
|
|
41
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ f("div", {
|
|
42
60
|
className: "flex items-start gap-4",
|
|
43
|
-
children: [/* @__PURE__ */
|
|
61
|
+
children: [/* @__PURE__ */ d("div", {
|
|
44
62
|
className: "flex h-16 w-16 items-center justify-center rounded-xl bg-action-primary-bg/10",
|
|
45
|
-
children: /* @__PURE__ */
|
|
46
|
-
}), /* @__PURE__ */
|
|
63
|
+
children: /* @__PURE__ */ d(s, { className: "h-8 w-8 text-primary" })
|
|
64
|
+
}), /* @__PURE__ */ f("div", {
|
|
47
65
|
className: "flex-1",
|
|
48
66
|
children: [
|
|
49
|
-
/* @__PURE__ */
|
|
67
|
+
/* @__PURE__ */ d("h2", {
|
|
50
68
|
className: "text-lg font-semibold text-text-primary",
|
|
51
|
-
children:
|
|
69
|
+
children: C
|
|
52
70
|
}),
|
|
53
|
-
/* @__PURE__ */
|
|
71
|
+
/* @__PURE__ */ d("p", {
|
|
54
72
|
className: "text-sm text-text-secondary",
|
|
55
|
-
children:
|
|
73
|
+
children: w
|
|
56
74
|
}),
|
|
57
|
-
/* @__PURE__ */
|
|
75
|
+
/* @__PURE__ */ f("div", {
|
|
58
76
|
className: "mt-2 flex items-center gap-3 text-sm text-text-secondary",
|
|
59
|
-
children: [/* @__PURE__ */
|
|
77
|
+
children: [/* @__PURE__ */ f("div", {
|
|
60
78
|
className: "flex items-center gap-1",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
62
|
-
}), /* @__PURE__ */
|
|
79
|
+
children: [/* @__PURE__ */ d(c, { className: "h-4 w-4 fill-amber-400 text-status-warning-text" }), /* @__PURE__ */ d("span", { children: T })]
|
|
80
|
+
}), /* @__PURE__ */ f("div", {
|
|
63
81
|
className: "flex items-center gap-1",
|
|
64
|
-
children: [/* @__PURE__ */
|
|
82
|
+
children: [/* @__PURE__ */ d(l, { className: "h-4 w-4" }), /* @__PURE__ */ f("span", { children: [E, " members"] })]
|
|
65
83
|
})]
|
|
66
84
|
})
|
|
67
85
|
]
|
|
68
86
|
})]
|
|
69
87
|
}),
|
|
70
|
-
|
|
88
|
+
D.length > 0 && /* @__PURE__ */ f("div", {
|
|
71
89
|
className: "mt-6",
|
|
72
|
-
children: [/* @__PURE__ */
|
|
90
|
+
children: [/* @__PURE__ */ d("h3", {
|
|
73
91
|
className: "text-sm font-semibold text-text-primary",
|
|
74
92
|
children: "Features"
|
|
75
|
-
}), /* @__PURE__ */
|
|
93
|
+
}), /* @__PURE__ */ d("ul", {
|
|
76
94
|
className: "mt-2 space-y-2",
|
|
77
|
-
children:
|
|
95
|
+
children: D.map((e) => /* @__PURE__ */ f("li", {
|
|
78
96
|
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
79
|
-
children: [/* @__PURE__ */
|
|
97
|
+
children: [/* @__PURE__ */ d(o, { className: "h-4 w-4 text-status-success-text" }), e]
|
|
80
98
|
}, e))
|
|
81
99
|
})]
|
|
82
100
|
}),
|
|
83
|
-
/* @__PURE__ */
|
|
101
|
+
/* @__PURE__ */ d("div", {
|
|
84
102
|
className: "mt-6 flex justify-end",
|
|
85
|
-
children: /* @__PURE__ */
|
|
103
|
+
children: /* @__PURE__ */ d("button", {
|
|
86
104
|
className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
87
105
|
children: "Apply Template"
|
|
88
106
|
})
|
|
89
107
|
})
|
|
90
108
|
]
|
|
91
|
-
})
|
|
109
|
+
})]
|
|
92
110
|
})
|
|
93
111
|
});
|
|
94
112
|
}
|
|
95
113
|
//#endregion
|
|
96
|
-
export {
|
|
114
|
+
export { h as TemplateDetailPage };
|
|
97
115
|
|
|
98
116
|
//# sourceMappingURL=TemplateDetailPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateDetailPage.js","names":[],"sources":["../../../../src/timecampus/pages/templates/TemplateDetailPage.tsx"],"sourcesContent":["import { useParams } from \"react-router-dom\";\nimport { Sparkles, ArrowLeft, Star, Users, CheckCircle } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport {
|
|
1
|
+
{"version":3,"file":"TemplateDetailPage.js","names":[],"sources":["../../../../src/timecampus/pages/templates/TemplateDetailPage.tsx"],"sourcesContent":["import { useParams } from \"react-router-dom\";\nimport { Sparkles, ArrowLeft, Star, Users, CheckCircle } from \"lucide-react\";\nimport { GlassCard, NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport {\n useTimeCampus,\n useTimeCampusNavigate,\n} from \"../../providers/TimeCampusProvider\";\nimport { useGetConfigurationQuery } from \"@/generated/wspace-operations\";\n\nexport function TemplateDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { workspaceId = \"\" } = useTimeCampus();\n const navigate = useTimeCampusNavigate();\n\n const { data, loading, error } = useGetConfigurationQuery({\n variables: { id: id ?? \"\" },\n skip: !id,\n });\n\n const config = data?.configuration;\n const val = (config?.value as Record<string, unknown>) ?? {};\n const name =\n (val.name as string) ?? config?.key?.replace(\"template.\", \"\") ?? \"Template\";\n const description =\n config?.description ??\n (val.description as string) ??\n \"A pre-built workspace template for time tracking workflows.\";\n const rating = (val.rating as number) ?? 0;\n const teamSize = (val.teamSize as string) ?? \"-\";\n const features = (val.features as string[]) ?? [];\n\n if (loading) {\n return (\n <PageLayout title=\"Template Details\" description=\"Loading...\">\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error || !config) {\n return (\n <PageLayout\n title=\"Template Details\"\n description={`Template ID: ${id}`}\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\">\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Templates\n </button>\n }\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 {error\n ? \"Failed to load template details. Please try again later.\"\n : \"Template configuration not found.\"}\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Template Details\"\n description={`Template ID: ${id}`}\n purpose=\"Review exactly what this template sets up — its features and who it's built for — before you apply it, so you know what will land in your workspace and whether it fits how your team works.\"\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\">\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Templates\n </button>\n }\n >\n <div className=\"mx-auto max-w-2xl\">\n <NextSteps\n storageKey=\"timecampus-template-detail\"\n className=\"mb-6\"\n steps={[\n {\n id: \"apply\",\n label: \"Apply this template\",\n description: \"Set up your workspace with this configuration.\",\n onClick: () => {},\n },\n {\n id: \"browse\",\n label: \"Browse other templates\",\n description: \"Compare with templates for other workflows.\",\n onClick: () => navigate(\"/templates\"),\n },\n ]}\n />\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-xl bg-action-primary-bg/10\">\n <Sparkles className=\"h-8 w-8 text-primary\" />\n </div>\n <div className=\"flex-1\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {name}\n </h2>\n <p className=\"text-sm text-text-secondary\">{description}</p>\n <div className=\"mt-2 flex items-center gap-3 text-sm text-text-secondary\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-4 w-4 fill-amber-400 text-status-warning-text\" />\n <span>{rating}</span>\n </div>\n <div className=\"flex items-center gap-1\">\n <Users className=\"h-4 w-4\" />\n <span>{teamSize} members</span>\n </div>\n </div>\n </div>\n </div>\n\n {features.length > 0 && (\n <div className=\"mt-6\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Features\n </h3>\n <ul className=\"mt-2 space-y-2\">\n {features.map((feature) => (\n <li\n key={feature}\n className=\"flex items-center gap-2 text-sm text-text-secondary\"\n >\n <CheckCircle className=\"h-4 w-4 text-status-success-text\" />\n {feature}\n </li>\n ))}\n </ul>\n </div>\n )}\n\n <div className=\"mt-6 flex justify-end\">\n <button className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\">\n Apply Template\n </button>\n </div>\n </GlassCard>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAWA,SAAgB,IAAqB;CACnC,IAAM,EAAE,UAAO,GAA2B,EACpC,EAAE,iBAAc,OAAO,GAAe,EACtC,IAAW,GAAuB,EAElC,EAAE,SAAM,YAAS,aAAU,EAAyB;EACxD,WAAW,EAAE,IAAI,KAAM,IAAI;EAC3B,MAAM,CAAC;EACR,CAAC,EAEI,IAAS,GAAM,eACf,IAAO,GAAQ,SAAqC,EAAE,EACtD,IACH,EAAI,QAAmB,GAAQ,KAAK,QAAQ,aAAa,GAAG,IAAI,YAC7D,IACJ,GAAQ,eACP,EAAI,eACL,+DACI,IAAU,EAAI,UAAqB,GACnC,IAAY,EAAI,YAAuB,KACvC,IAAY,EAAI,YAAyB,EAAE;AA+BjD,QA7BI,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAmB,aAAY;YAC/C,kBAAC,GAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,CAAA,GAIb,KAAS,CAAC,IAEV,kBAAC,GAAD;EACE,OAAM;EACN,aAAa,gBAAgB;EAC7B,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,oBAE1B;;YAGX,kBAAC,OAAD;GAAK,WAAU;aACZ,IACG,6DACA;GACA,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAa,gBAAgB;EAC7B,SAAQ;EACR,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,oBAE1B;;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IACE,YAAW;IACX,WAAU;IACV,OAAO,CACL;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,eAAe;KAChB,EACD;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,eAAe,EAAS,aAAa;KACtC,CACF;IACD,CAAA,EACF,kBAAC,GAAD;IAAW,WAAU;IAAQ,MAAA;IAAK,WAAU;cAA5C;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAU,WAAU,wBAAyB,CAAA;OACzC,CAAA,EACN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,MAAD;SAAI,WAAU;mBACX;SACE,CAAA;QACL,kBAAC,KAAD;SAAG,WAAU;mBAA+B;SAAgB,CAAA;QAC5D,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,mDAAoD,CAAA,EACpE,kBAAC,QAAD,EAAA,UAAO,GAAc,CAAA,CACjB;aACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA,EAC7B,kBAAC,QAAD,EAAA,UAAA,CAAO,GAAS,WAAe,EAAA,CAAA,CAC3B;YACF;;QACF;SACF;;KAEL,EAAS,SAAS,KACjB,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBAA0C;OAEnD,CAAA,EACL,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAS,KAAK,MACb,kBAAC,MAAD;QAEE,WAAU;kBAFZ,CAIE,kBAAC,GAAD,EAAa,WAAU,oCAAqC,CAAA,EAC3D,EACE;UALE,EAKF,CACL;OACC,CAAA,CACD;;KAGR,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,UAAD;OAAQ,WAAU;iBAAuH;OAEhI,CAAA;MACL,CAAA;KACI;MACR;;EACK,CAAA"}
|
|
@@ -2,68 +2,71 @@ 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 { Sparkles as a, Star as o, Users as s } from "lucide-react";
|
|
7
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
7
8
|
//#region src/timecampus/pages/templates/TemplatesPage.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("template."));
|
|
11
|
+
return f ? /* @__PURE__ */ c(r, {
|
|
11
12
|
title: "Templates",
|
|
12
13
|
description: "Pre-built workspace templates for different workflows",
|
|
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: "Templates",
|
|
19
20
|
description: "Pre-built workspace templates for different workflows",
|
|
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 template configurations. Please try again later."
|
|
23
24
|
})
|
|
24
|
-
}) : /* @__PURE__ */
|
|
25
|
+
}) : /* @__PURE__ */ c(r, {
|
|
25
26
|
title: "Templates",
|
|
26
27
|
description: "Pre-built workspace templates for different workflows",
|
|
27
|
-
|
|
28
|
+
purpose: "Skip the blank-page setup — apply a ready-made template that pre-loads projects, categories and settings for a common workflow, so a new team or workspace is productive in minutes.",
|
|
29
|
+
children: m.length === 0 ? /* @__PURE__ */ c(i, {
|
|
30
|
+
illustration: "empty-generic",
|
|
31
|
+
title: "No templates configured yet",
|
|
32
|
+
description: "Templates are stored as workspace configurations with the 'template.' key prefix — once added, ready-to-apply workflow setups appear here."
|
|
33
|
+
}) : /* @__PURE__ */ c("div", {
|
|
28
34
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
29
|
-
children:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}) : p.map((e) => {
|
|
33
|
-
let t = e.value, n = t.name ?? e.key.replace("template.", ""), r = t.category ?? "General", l = t.industry ?? "Any", u = t.rating ?? 0, d = t.teamSize ?? "-", f = t.downloads ?? 0;
|
|
34
|
-
return /* @__PURE__ */ c("div", {
|
|
35
|
+
children: m.map((e) => {
|
|
36
|
+
let t = e.value, n = t.name ?? e.key.replace("template.", ""), r = t.category ?? "General", i = t.industry ?? "Any", u = t.rating ?? 0, d = t.teamSize ?? "-", f = t.downloads ?? 0;
|
|
37
|
+
return /* @__PURE__ */ l("div", {
|
|
35
38
|
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-5 transition-colors hover:bg-bg-sunken/50 cursor-pointer",
|
|
36
|
-
children: [/* @__PURE__ */
|
|
39
|
+
children: [/* @__PURE__ */ l("div", {
|
|
37
40
|
className: "flex items-start gap-3",
|
|
38
|
-
children: [/* @__PURE__ */
|
|
41
|
+
children: [/* @__PURE__ */ c("div", {
|
|
39
42
|
className: "flex h-12 w-12 items-center justify-center rounded-xl bg-action-primary-bg/10",
|
|
40
|
-
children: /* @__PURE__ */
|
|
41
|
-
}), /* @__PURE__ */
|
|
43
|
+
children: /* @__PURE__ */ c(a, { className: "h-6 w-6 text-primary" })
|
|
44
|
+
}), /* @__PURE__ */ l("div", {
|
|
42
45
|
className: "flex-1",
|
|
43
|
-
children: [/* @__PURE__ */
|
|
46
|
+
children: [/* @__PURE__ */ c("p", {
|
|
44
47
|
className: "text-sm font-semibold text-text-primary",
|
|
45
48
|
children: n
|
|
46
|
-
}), /* @__PURE__ */
|
|
49
|
+
}), /* @__PURE__ */ l("p", {
|
|
47
50
|
className: "text-xs text-text-secondary",
|
|
48
51
|
children: [
|
|
49
52
|
r,
|
|
50
53
|
" · ",
|
|
51
|
-
|
|
54
|
+
i
|
|
52
55
|
]
|
|
53
56
|
})]
|
|
54
57
|
})]
|
|
55
|
-
}), /* @__PURE__ */
|
|
58
|
+
}), /* @__PURE__ */ l("div", {
|
|
56
59
|
className: "mt-3 flex items-center justify-between text-xs text-text-secondary",
|
|
57
|
-
children: [/* @__PURE__ */
|
|
60
|
+
children: [/* @__PURE__ */ l("div", {
|
|
58
61
|
className: "flex items-center gap-3",
|
|
59
|
-
children: [/* @__PURE__ */
|
|
62
|
+
children: [/* @__PURE__ */ l("div", {
|
|
60
63
|
className: "flex items-center gap-1",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
62
|
-
}), /* @__PURE__ */
|
|
64
|
+
children: [/* @__PURE__ */ c(o, { className: "h-3 w-3 fill-amber-400 text-status-warning-text" }), /* @__PURE__ */ c("span", { children: u })]
|
|
65
|
+
}), /* @__PURE__ */ l("div", {
|
|
63
66
|
className: "flex items-center gap-1",
|
|
64
|
-
children: [/* @__PURE__ */ s
|
|
67
|
+
children: [/* @__PURE__ */ c(s, { className: "h-3 w-3" }), /* @__PURE__ */ c("span", { children: d })]
|
|
65
68
|
})]
|
|
66
|
-
}), /* @__PURE__ */
|
|
69
|
+
}), /* @__PURE__ */ l("span", { children: [f, " uses"] })]
|
|
67
70
|
})]
|
|
68
71
|
}, e.id);
|
|
69
72
|
})
|
|
@@ -71,6 +74,6 @@ function l() {
|
|
|
71
74
|
});
|
|
72
75
|
}
|
|
73
76
|
//#endregion
|
|
74
|
-
export {
|
|
77
|
+
export { u as TemplatesPage };
|
|
75
78
|
|
|
76
79
|
//# sourceMappingURL=TemplatesPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplatesPage.js","names":[],"sources":["../../../../src/timecampus/pages/templates/TemplatesPage.tsx"],"sourcesContent":["import { Sparkles, Star, Users } 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 TemplatesPage() {\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 templates (key starts with 'template.')\n const templates = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"template.\"),\n );\n\n if (loading) {\n return (\n <PageLayout\n title=\"Templates\"\n description=\"Pre-built workspace templates for different workflows\"\n >\n <LoadingSkeleton variant=\"card\" count={6} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Templates\"\n description=\"Pre-built workspace templates for different workflows\"\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 template configurations. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Templates\"\n description=\"Pre-built workspace templates for different workflows\"\n
|
|
1
|
+
{"version":3,"file":"TemplatesPage.js","names":[],"sources":["../../../../src/timecampus/pages/templates/TemplatesPage.tsx"],"sourcesContent":["import { Sparkles, Star, Users } 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 TemplatesPage() {\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 templates (key starts with 'template.')\n const templates = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"template.\"),\n );\n\n if (loading) {\n return (\n <PageLayout\n title=\"Templates\"\n description=\"Pre-built workspace templates for different workflows\"\n >\n <LoadingSkeleton variant=\"card\" count={6} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Templates\"\n description=\"Pre-built workspace templates for different workflows\"\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 template configurations. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Templates\"\n description=\"Pre-built workspace templates for different workflows\"\n purpose=\"Skip the blank-page setup — apply a ready-made template that pre-loads projects, categories and settings for a common workflow, so a new team or workspace is productive in minutes.\"\n >\n {templates.length === 0 ? (\n <EmptyState\n illustration=\"empty-generic\"\n title=\"No templates configured yet\"\n description=\"Templates are stored as workspace configurations with the 'template.' key prefix — once added, ready-to-apply workflow setups appear here.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {templates.map((template: ConfigurationFieldsFragment) => {\n const val = template.value as Record<string, unknown>;\n const name =\n (val.name as string) ?? template.key.replace(\"template.\", \"\");\n const category = (val.category as string) ?? \"General\";\n const industry = (val.industry as string) ?? \"Any\";\n const rating = (val.rating as number) ?? 0;\n const teamSize = (val.teamSize as string) ?? \"-\";\n const downloads = (val.downloads as number) ?? 0;\n\n return (\n <div\n key={template.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 <Sparkles 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\">\n {category} · {industry}\n </p>\n </div>\n </div>\n <div className=\"mt-3 flex items-center justify-between text-xs text-text-secondary\">\n <div className=\"flex items-center gap-3\">\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 <Users className=\"h-3 w-3\" />\n <span>{teamSize}</span>\n </div>\n </div>\n <span>{downloads} uses</span>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAUA,SAAgB,IAAgB;CAC9B,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA2B,EAC1D,WAAW,EAAE,OAAO,aAAoB,EACzC,CAAC,EAKI,KAHiB,GAAM,kBAAkB,EAAE,EAGhB,QAAQ,MACvC,EAAE,IAAI,WAAW,YAAY,CAC9B;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,EAAU,WAAW,IACpB,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAU,KAAK,MAA0C;IACxD,IAAM,IAAM,EAAS,OACf,IACH,EAAI,QAAmB,EAAS,IAAI,QAAQ,aAAa,GAAG,EACzD,IAAY,EAAI,YAAuB,WACvC,IAAY,EAAI,YAAuB,OACvC,IAAU,EAAI,UAAqB,GACnC,IAAY,EAAI,YAAuB,KACvC,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,EAAU,WAAU,wBAAyB,CAAA;OACzC,CAAA,EACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV;QACC,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG;SAAS;SAAW;SACnB;UACA;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,EAAO,WAAU,WAAY,CAAA,EAC7B,kBAAC,QAAD,EAAA,UAAO,GAAgB,CAAA,CACnB;UACF;UACN,kBAAC,QAAD,EAAA,UAAA,CAAO,GAAU,QAAY,EAAA,CAAA,CACzB;QACF;OA7BC,EAAS,GA6BV;KAER;GACE,CAAA;EAEG,CAAA"}
|
|
@@ -2,109 +2,118 @@ import { formatDate as e, formatHours as t, getStatusColor as n } from "../../ut
|
|
|
2
2
|
import { LoadingSkeleton as r } from "../../components/LoadingSkeleton.js";
|
|
3
3
|
import { useListTimeEntriesQuery as i } from "../../../generated/wspace-operations.js";
|
|
4
4
|
import { PageLayout as a } from "../../components/PageLayout.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { EmptyState as o } from "../../components/EmptyState.js";
|
|
6
|
+
import { Filter as s, Plus as c } from "lucide-react";
|
|
7
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
|
+
import { GlassCard as d } from "@burdenoff/fe-libs/ui";
|
|
7
9
|
//#region src/timecampus/pages/time/TimeEntriesPage.tsx
|
|
8
|
-
function
|
|
9
|
-
let { data:
|
|
10
|
-
return
|
|
10
|
+
function f() {
|
|
11
|
+
let { data: f, loading: p, error: m } = i({ variables: { limit: 50 } }), h = f?.timeEntries?.items ?? [];
|
|
12
|
+
return m ? /* @__PURE__ */ l(a, {
|
|
11
13
|
title: "Time Entries",
|
|
12
14
|
description: "View and manage all time entries",
|
|
13
|
-
children: /* @__PURE__ */
|
|
15
|
+
children: /* @__PURE__ */ l("div", {
|
|
14
16
|
className: "rounded-xl border border-status-error-bg/40 bg-status-error-bg p-6 text-sm text-status-error-text",
|
|
15
17
|
children: "Failed to load time entries. Please try again later."
|
|
16
18
|
})
|
|
17
|
-
}) : /* @__PURE__ */
|
|
19
|
+
}) : /* @__PURE__ */ l(a, {
|
|
18
20
|
title: "Time Entries",
|
|
19
21
|
description: "View and manage all time entries",
|
|
20
|
-
|
|
22
|
+
purpose: "Every tracked block of work in one auditable list — filter, correct and confirm entries here before they roll into timesheets, approvals and client invoices.",
|
|
23
|
+
actions: /* @__PURE__ */ u("div", {
|
|
21
24
|
className: "flex items-center gap-2",
|
|
22
|
-
children: [/* @__PURE__ */
|
|
25
|
+
children: [/* @__PURE__ */ u("button", {
|
|
23
26
|
className: "inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
|
|
24
|
-
children: [/* @__PURE__ */
|
|
25
|
-
}), /* @__PURE__ */
|
|
27
|
+
children: [/* @__PURE__ */ l(s, { className: "h-4 w-4" }), "Filter"]
|
|
28
|
+
}), /* @__PURE__ */ u("button", {
|
|
26
29
|
className: "inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
27
|
-
children: [/* @__PURE__ */ c
|
|
30
|
+
children: [/* @__PURE__ */ l(c, { className: "h-4 w-4" }), "Add Entry"]
|
|
28
31
|
})]
|
|
29
32
|
}),
|
|
30
|
-
children:
|
|
33
|
+
children: p ? /* @__PURE__ */ l(r, {
|
|
31
34
|
variant: "table",
|
|
32
35
|
count: 5
|
|
33
|
-
}) : /* @__PURE__ */
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
}) : h.length === 0 ? /* @__PURE__ */ l(o, {
|
|
37
|
+
illustration: "empty-data",
|
|
38
|
+
title: "No time entries found",
|
|
39
|
+
description: "Track time with a timer or add a manual entry — your entries will appear here.",
|
|
40
|
+
action: /* @__PURE__ */ u("button", {
|
|
41
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
42
|
+
children: [/* @__PURE__ */ l(c, { className: "h-4 w-4" }), "Add Entry"]
|
|
43
|
+
})
|
|
44
|
+
}) : /* @__PURE__ */ l(d, {
|
|
45
|
+
treatment: "glass",
|
|
46
|
+
glow: !0,
|
|
47
|
+
className: "overflow-hidden",
|
|
48
|
+
children: /* @__PURE__ */ l("div", {
|
|
36
49
|
className: "overflow-x-auto",
|
|
37
|
-
children: /* @__PURE__ */
|
|
50
|
+
children: /* @__PURE__ */ u("table", {
|
|
38
51
|
className: "w-full",
|
|
39
|
-
children: [/* @__PURE__ */
|
|
52
|
+
children: [/* @__PURE__ */ l("thead", { children: /* @__PURE__ */ u("tr", {
|
|
40
53
|
className: "border-b border-border-subtle",
|
|
41
54
|
children: [
|
|
42
|
-
/* @__PURE__ */
|
|
55
|
+
/* @__PURE__ */ l("th", {
|
|
43
56
|
className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
|
|
44
57
|
children: "Date"
|
|
45
58
|
}),
|
|
46
|
-
/* @__PURE__ */
|
|
59
|
+
/* @__PURE__ */ l("th", {
|
|
47
60
|
className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
|
|
48
61
|
children: "Project"
|
|
49
62
|
}),
|
|
50
|
-
/* @__PURE__ */
|
|
63
|
+
/* @__PURE__ */ l("th", {
|
|
51
64
|
className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
|
|
52
65
|
children: "Task"
|
|
53
66
|
}),
|
|
54
|
-
/* @__PURE__ */
|
|
67
|
+
/* @__PURE__ */ l("th", {
|
|
55
68
|
className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
|
|
56
69
|
children: "Duration"
|
|
57
70
|
}),
|
|
58
|
-
/* @__PURE__ */
|
|
71
|
+
/* @__PURE__ */ l("th", {
|
|
59
72
|
className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
|
|
60
73
|
children: "Billable"
|
|
61
74
|
}),
|
|
62
|
-
/* @__PURE__ */
|
|
75
|
+
/* @__PURE__ */ l("th", {
|
|
63
76
|
className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
|
|
64
77
|
children: "Status"
|
|
65
78
|
})
|
|
66
79
|
]
|
|
67
80
|
}) }), /* @__PURE__ */ l("tbody", {
|
|
68
81
|
className: "divide-y divide-border",
|
|
69
|
-
children:
|
|
82
|
+
children: h.map((r) => /* @__PURE__ */ u("tr", {
|
|
70
83
|
className: "hover:bg-bg-sunken/50 transition-colors",
|
|
71
84
|
children: [
|
|
72
|
-
/* @__PURE__ */
|
|
85
|
+
/* @__PURE__ */ l("td", {
|
|
73
86
|
className: "px-4 py-3 text-sm text-text-secondary",
|
|
74
87
|
children: e(r.startTime)
|
|
75
88
|
}),
|
|
76
|
-
/* @__PURE__ */
|
|
89
|
+
/* @__PURE__ */ l("td", {
|
|
77
90
|
className: "px-4 py-3 text-sm font-medium text-text-primary",
|
|
78
91
|
children: r.project?.name ?? "No Project"
|
|
79
92
|
}),
|
|
80
|
-
/* @__PURE__ */
|
|
93
|
+
/* @__PURE__ */ l("td", {
|
|
81
94
|
className: "px-4 py-3 text-sm text-text-secondary",
|
|
82
95
|
children: r.task?.title ?? r.description ?? "No description"
|
|
83
96
|
}),
|
|
84
|
-
/* @__PURE__ */
|
|
97
|
+
/* @__PURE__ */ l("td", {
|
|
85
98
|
className: "px-4 py-3 text-sm font-mono text-text-primary",
|
|
86
99
|
children: t((r.duration ?? 0) / 3600)
|
|
87
100
|
}),
|
|
88
|
-
/* @__PURE__ */
|
|
101
|
+
/* @__PURE__ */ l("td", {
|
|
89
102
|
className: "px-4 py-3",
|
|
90
|
-
children: /* @__PURE__ */
|
|
103
|
+
children: /* @__PURE__ */ l("span", {
|
|
91
104
|
className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${r.billable ? "bg-status-success-bg text-status-success-text" : "bg-bg-sunken text-text-secondary"}`,
|
|
92
105
|
children: r.billable ? "Yes" : "No"
|
|
93
106
|
})
|
|
94
107
|
}),
|
|
95
|
-
/* @__PURE__ */
|
|
108
|
+
/* @__PURE__ */ l("td", {
|
|
96
109
|
className: "px-4 py-3",
|
|
97
|
-
children: /* @__PURE__ */
|
|
110
|
+
children: /* @__PURE__ */ l("span", {
|
|
98
111
|
className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${n(r.isRunning ? "running" : "completed")}`,
|
|
99
112
|
children: r.isRunning ? "running" : "completed"
|
|
100
113
|
})
|
|
101
114
|
})
|
|
102
115
|
]
|
|
103
|
-
}, r.id))
|
|
104
|
-
colSpan: 6,
|
|
105
|
-
className: "px-4 py-8 text-center text-sm text-text-secondary",
|
|
106
|
-
children: "No time entries found"
|
|
107
|
-
}) })]
|
|
116
|
+
}, r.id))
|
|
108
117
|
})]
|
|
109
118
|
})
|
|
110
119
|
})
|
|
@@ -112,6 +121,6 @@ function u() {
|
|
|
112
121
|
});
|
|
113
122
|
}
|
|
114
123
|
//#endregion
|
|
115
|
-
export {
|
|
124
|
+
export { f as TimeEntriesPage };
|
|
116
125
|
|
|
117
126
|
//# sourceMappingURL=TimeEntriesPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeEntriesPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimeEntriesPage.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"TimeEntriesPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimeEntriesPage.tsx"],"sourcesContent":["import { Plus, Filter } 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 { formatHours, formatDate, getStatusColor } from \"../../utils/helpers\";\nimport {\n useListTimeEntriesQuery,\n type TimeEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function TimeEntriesPage() {\n const { data, loading, error } = useListTimeEntriesQuery({\n variables: { limit: 50 },\n });\n\n const entries = data?.timeEntries?.items ?? [];\n\n if (error) {\n return (\n <PageLayout\n title=\"Time Entries\"\n description=\"View and manage all time entries\"\n >\n <div className=\"rounded-xl border border-status-error-bg/40 bg-status-error-bg p-6 text-sm text-status-error-text\">\n Failed to load time entries. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Time Entries\"\n description=\"View and manage all time entries\"\n purpose=\"Every tracked block of work in one auditable list — filter, correct and confirm entries here before they roll into timesheets, approvals and client invoices.\"\n actions={\n <div className=\"flex items-center gap-2\">\n <button className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\">\n <Filter className=\"h-4 w-4\" />\n Filter\n </button>\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\">\n <Plus className=\"h-4 w-4\" />\n Add Entry\n </button>\n </div>\n }\n >\n {loading ? (\n <LoadingSkeleton variant=\"table\" count={5} />\n ) : entries.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No time entries found\"\n description=\"Track time with a timer or add a manual entry — your entries will appear here.\"\n action={\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\">\n <Plus className=\"h-4 w-4\" />\n Add Entry\n </button>\n }\n />\n ) : (\n <GlassCard treatment=\"glass\" glow className=\"overflow-hidden\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-subtle\">\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Date\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Project\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Task\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Duration\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Billable\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Status\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {entries.map((entry: TimeEntryFieldsFragment) => (\n <tr\n key={entry.id}\n className=\"hover:bg-bg-sunken/50 transition-colors\"\n >\n <td className=\"px-4 py-3 text-sm text-text-secondary\">\n {formatDate(entry.startTime)}\n </td>\n <td className=\"px-4 py-3 text-sm font-medium text-text-primary\">\n {entry.project?.name ?? \"No Project\"}\n </td>\n <td className=\"px-4 py-3 text-sm text-text-secondary\">\n {entry.task?.title ??\n entry.description ??\n \"No description\"}\n </td>\n <td className=\"px-4 py-3 text-sm font-mono text-text-primary\">\n {formatHours((entry.duration ?? 0) / 3600)}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${entry.billable ? \"bg-status-success-bg text-status-success-text\" : \"bg-bg-sunken text-text-secondary\"}`}\n >\n {entry.billable ? \"Yes\" : \"No\"}\n </span>\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(entry.isRunning ? \"running\" : \"completed\")}`}\n >\n {entry.isRunning ? \"running\" : \"completed\"}\n </span>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </GlassCard>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAWA,SAAgB,IAAkB;CAChC,IAAM,EAAE,SAAM,YAAS,aAAU,EAAwB,EACvD,WAAW,EAAE,OAAO,IAAI,EACzB,CAAC,EAEI,IAAU,GAAM,aAAa,SAAS,EAAE;AAe9C,QAbI,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;EACR,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,SAEvB;OACT,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,YAErB;MACL;;YAGP,IACC,kBAAC,GAAD;GAAiB,SAAQ;GAAQ,OAAO;GAAK,CAAA,GAC3C,EAAQ,WAAW,IACrB,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,QACE,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,YAErB;;GAEX,CAAA,GAEF,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAC1C,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACE,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACF;SACC,CAAA,EACR,kBAAC,SAAD;MAAO,WAAU;gBACd,EAAQ,KAAK,MACZ,kBAAC,MAAD;OAEE,WAAU;iBAFZ;QAIE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAW,EAAM,UAAU;SACzB,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAM,SAAS,QAAQ;SACrB,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAM,MAAM,SACX,EAAM,eACN;SACC,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACX,GAAa,EAAM,YAAY,KAAK,KAAK;SACvC,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,QAAD;UACE,WAAW,4DAA4D,EAAM,WAAW,kDAAkD;oBAEzI,EAAM,WAAW,QAAQ;UACrB,CAAA;SACJ,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,QAAD;UACE,WAAW,4DAA4D,EAAe,EAAM,YAAY,YAAY,YAAY;oBAE/H,EAAM,YAAY,YAAY;UAC1B,CAAA;SACJ,CAAA;QACF;SA/BE,EAAM,GA+BR,CACL;MACI,CAAA,CACF;;IACJ,CAAA;GACI,CAAA;EAEH,CAAA"}
|