@igstack/app-catalog-frontend-core 6.10.3 → 6.11.0
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/esm/__tests__/modules/auth/AuthContext.test.d.ts +1 -0
- package/dist/esm/__tests__/modules/communityTools/likedBy.test.d.ts +1 -0
- package/dist/esm/__tests__/modules/communityTools/timeAgo.test.d.ts +1 -0
- package/dist/esm/__tests__/modules/communityTools/useTimeUp.test.d.ts +1 -0
- package/dist/esm/api/infra/trpc.d.ts +419 -0
- package/dist/esm/api/infra/trpc.js.map +1 -1
- package/dist/esm/modules/appCatalog/hooks/useUpdateApp.d.ts +1 -1
- package/dist/esm/modules/appCatalog/ui/catalog/AppDetailPanel.d.ts +2 -4
- package/dist/esm/modules/appCatalog/ui/catalog/AppDetailPanel.js +29 -101
- package/dist/esm/modules/appCatalog/ui/catalog/AppDetailPanel.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/catalog/DetailDialogShell.d.ts +26 -0
- package/dist/esm/modules/appCatalog/ui/catalog/DetailDialogShell.js +108 -0
- package/dist/esm/modules/appCatalog/ui/catalog/DetailDialogShell.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/components/ScreenshotGallery.d.ts +2 -1
- package/dist/esm/modules/appCatalog/ui/components/ScreenshotGallery.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/components/SectionTabs.d.ts +8 -0
- package/dist/esm/modules/appCatalog/ui/components/SectionTabs.js +73 -0
- package/dist/esm/modules/appCatalog/ui/components/SectionTabs.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/detail/AppDetails.js +19 -2
- package/dist/esm/modules/appCatalog/ui/detail/AppDetails.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/CommentsFeed.d.ts +3 -2
- package/dist/esm/modules/appCatalog/ui/detail/CommentsFeed.js +4 -4
- package/dist/esm/modules/appCatalog/ui/detail/CommentsFeed.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/CommentsHelp.d.ts +2 -1
- package/dist/esm/modules/appCatalog/ui/detail/CommentsHelp.js +2 -2
- package/dist/esm/modules/appCatalog/ui/detail/CommentsHelp.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/CommunityInput.d.ts +3 -2
- package/dist/esm/modules/appCatalog/ui/detail/CommunityInput.js +13 -9
- package/dist/esm/modules/appCatalog/ui/detail/CommunityInput.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/CommunitySection.d.ts +4 -2
- package/dist/esm/modules/appCatalog/ui/detail/CommunitySection.js +10 -4
- package/dist/esm/modules/appCatalog/ui/detail/CommunitySection.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/communityDraft.d.ts +12 -0
- package/dist/esm/modules/appCatalog/ui/detail/communityDraft.js +4 -0
- package/dist/esm/modules/appCatalog/ui/detail/communityDraft.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/composeComments.js +1 -0
- package/dist/esm/modules/appCatalog/ui/detail/composeComments.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/useCommunityToolCount.d.ts +6 -0
- package/dist/esm/modules/appCatalog/ui/detail/useCommunityToolCount.js +16 -0
- package/dist/esm/modules/appCatalog/ui/detail/useCommunityToolCount.js.map +1 -0
- package/dist/esm/modules/appCatalog/ui/layout/AppCatalogLayout.js +2 -2
- package/dist/esm/modules/appCatalog/ui/layout/AppCatalogLayout.js.map +1 -1
- package/dist/esm/modules/auth/AuthContext.js +7 -3
- package/dist/esm/modules/auth/AuthContext.js.map +1 -1
- package/dist/esm/modules/auth/ui/LoginModal.js +16 -8
- package/dist/esm/modules/auth/ui/LoginModal.js.map +1 -1
- package/dist/esm/modules/communityTools/likedBy.d.ts +8 -0
- package/dist/esm/modules/communityTools/likedBy.js +23 -0
- package/dist/esm/modules/communityTools/likedBy.js.map +1 -0
- package/dist/esm/modules/communityTools/timeAgo.d.ts +2 -0
- package/dist/esm/modules/communityTools/timeAgo.js +18 -0
- package/dist/esm/modules/communityTools/timeAgo.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/CardScreenshot.d.ts +13 -0
- package/dist/esm/modules/communityTools/ui/CardScreenshot.js +112 -0
- package/dist/esm/modules/communityTools/ui/CardScreenshot.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/CardTitleBlock.d.ts +8 -0
- package/dist/esm/modules/communityTools/ui/CardTitleBlock.js +59 -0
- package/dist/esm/modules/communityTools/ui/CardTitleBlock.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/CommunityPage.d.ts +12 -0
- package/dist/esm/modules/communityTools/ui/CommunityPage.js +547 -0
- package/dist/esm/modules/communityTools/ui/CommunityPage.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/FeedRow.d.ts +42 -0
- package/dist/esm/modules/communityTools/ui/FeedRow.js +260 -0
- package/dist/esm/modules/communityTools/ui/FeedRow.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/FeedSortControl.d.ts +17 -0
- package/dist/esm/modules/communityTools/ui/FeedSortControl.js +84 -0
- package/dist/esm/modules/communityTools/ui/FeedSortControl.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/LifecycleBadge.d.ts +7 -0
- package/dist/esm/modules/communityTools/ui/LifecycleBadge.js +50 -0
- package/dist/esm/modules/communityTools/ui/LifecycleBadge.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/LikeButton.d.ts +9 -0
- package/dist/esm/modules/communityTools/ui/LikeButton.js +56 -0
- package/dist/esm/modules/communityTools/ui/LikeButton.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/MarginPreview.d.ts +18 -0
- package/dist/esm/modules/communityTools/ui/MarginPreview.js +115 -0
- package/dist/esm/modules/communityTools/ui/MarginPreview.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/MyToolsShelf.d.ts +12 -0
- package/dist/esm/modules/communityTools/ui/MyToolsShelf.js +88 -0
- package/dist/esm/modules/communityTools/ui/MyToolsShelf.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/OwnerPicker.d.ts +56 -0
- package/dist/esm/modules/communityTools/ui/OwnerPicker.js +245 -0
- package/dist/esm/modules/communityTools/ui/OwnerPicker.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/PinButton.d.ts +14 -0
- package/dist/esm/modules/communityTools/ui/PinButton.js +72 -0
- package/dist/esm/modules/communityTools/ui/PinButton.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/ShelfTile.d.ts +13 -0
- package/dist/esm/modules/communityTools/ui/ShelfTile.js +81 -0
- package/dist/esm/modules/communityTools/ui/ShelfTile.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/TagPicker.d.ts +21 -0
- package/dist/esm/modules/communityTools/ui/TagPicker.js +87 -0
- package/dist/esm/modules/communityTools/ui/TagPicker.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/TagRow.d.ts +22 -0
- package/dist/esm/modules/communityTools/ui/TagRow.js +92 -0
- package/dist/esm/modules/communityTools/ui/TagRow.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/Toast.d.ts +19 -0
- package/dist/esm/modules/communityTools/ui/Toast.js +87 -0
- package/dist/esm/modules/communityTools/ui/Toast.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/ToolCard.d.ts +22 -0
- package/dist/esm/modules/communityTools/ui/ToolCard.js +467 -0
- package/dist/esm/modules/communityTools/ui/ToolCard.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/ToolFormDialog.d.ts +32 -0
- package/dist/esm/modules/communityTools/ui/ToolFormDialog.js +765 -0
- package/dist/esm/modules/communityTools/ui/ToolFormDialog.js.map +1 -0
- package/dist/esm/modules/communityTools/ui/ToolSearch.d.ts +15 -0
- package/dist/esm/modules/communityTools/ui/ToolSearch.js +92 -0
- package/dist/esm/modules/communityTools/ui/ToolSearch.js.map +1 -0
- package/dist/esm/modules/communityTools/useCommunityTools.d.ts +157 -0
- package/dist/esm/modules/communityTools/useCommunityTools.js +122 -0
- package/dist/esm/modules/communityTools/useCommunityTools.js.map +1 -0
- package/dist/esm/modules/communityTools/useCommunityToolsConfig.d.ts +10 -0
- package/dist/esm/modules/communityTools/useCommunityToolsConfig.js +20 -0
- package/dist/esm/modules/communityTools/useCommunityToolsConfig.js.map +1 -0
- package/dist/esm/modules/communityTools/useTimeUp.d.ts +5 -0
- package/dist/esm/modules/communityTools/useTimeUp.js +13 -0
- package/dist/esm/modules/communityTools/useTimeUp.js.map +1 -0
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/classic/schemas.js +2 -2
- package/dist/esm/node_modules/.pnpm/zod@4.3.5/node_modules/zod/v4/core/schemas.js +1 -1
- package/dist/esm/routeTree.gen.d.ts +96 -3
- package/dist/esm/routeTree.gen.js +19 -0
- package/dist/esm/routeTree.gen.js.map +1 -1
- package/dist/esm/routes/_layout/community.$slug.d.ts +22 -0
- package/dist/esm/routes/_layout/community._slug.js +10 -0
- package/dist/esm/routes/_layout/community._slug.js.map +1 -0
- package/dist/esm/routes/_layout/community.d.ts +23 -0
- package/dist/esm/routes/_layout/community.js +71 -0
- package/dist/esm/routes/_layout/community.js.map +1 -0
- package/dist/esm/ui/components/header/Header.js +7 -3
- package/dist/esm/ui/components/header/Header.js.map +1 -1
- package/dist/esm/util/highlightMatches.d.ts +2 -0
- package/dist/esm/util/highlightMatches.js +32 -0
- package/dist/esm/util/highlightMatches.js.map +1 -0
- package/dist/index.css +6 -0
- package/package.json +5 -5
- package/src/__tests__/modules/appCatalog/ui/catalog/AppDetailPanel.appSwitch.test.tsx +3 -0
- package/src/__tests__/modules/appCatalog/ui/catalog/AppDetailPanel.enter.test.tsx +3 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.background.test.tsx +3 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.behindThisCard.test.tsx +4 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.doorAndTabs.test.tsx +3 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.escape.test.tsx +3 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.knowMore.test.tsx +3 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.sectionOrder.test.tsx +3 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.subResourceTab.test.tsx +3 -0
- package/src/__tests__/modules/appCatalog/ui/detail/AppDetails.tags.test.tsx +3 -0
- package/src/__tests__/modules/appCatalog/ui/detail/CommunitySection.feed.test.tsx +10 -3
- package/src/__tests__/modules/appCatalog/ui/detail/CommunitySection.help.test.tsx +4 -1
- package/src/__tests__/modules/appCatalog/ui/detail/CommunitySection.input.test.tsx +12 -2
- package/src/__tests__/modules/appCatalog/ui/detail/composeComments.test.ts +1 -0
- package/src/__tests__/modules/auth/AuthContext.test.tsx +55 -0
- package/src/__tests__/modules/communityTools/likedBy.test.ts +45 -0
- package/src/__tests__/modules/communityTools/timeAgo.test.ts +28 -0
- package/src/__tests__/modules/communityTools/useTimeUp.test.ts +31 -0
- package/src/__tests__/ui/components/header/Header.login.test.tsx +4 -4
- package/src/api/infra/trpc.ts +2 -0
- package/src/index.css +6 -0
- package/src/modules/appCatalog/ui/catalog/AppDetailPanel.tsx +33 -176
- package/src/modules/appCatalog/ui/catalog/DetailDialogShell.tsx +199 -0
- package/src/modules/appCatalog/ui/components/ScreenshotGallery.tsx +2 -1
- package/src/modules/appCatalog/ui/components/SectionTabs.tsx +81 -0
- package/src/modules/appCatalog/ui/detail/AppDetails.tsx +17 -2
- package/src/modules/appCatalog/ui/detail/CommentsFeed.tsx +9 -4
- package/src/modules/appCatalog/ui/detail/CommentsHelp.tsx +6 -3
- package/src/modules/appCatalog/ui/detail/CommunityInput.tsx +15 -10
- package/src/modules/appCatalog/ui/detail/CommunitySection.tsx +10 -5
- package/src/modules/appCatalog/ui/detail/communityDraft.ts +16 -0
- package/src/modules/appCatalog/ui/detail/composeComments.ts +1 -0
- package/src/modules/appCatalog/ui/detail/useCommunityToolCount.ts +18 -0
- package/src/modules/appCatalog/ui/layout/AppCatalogLayout.tsx +2 -2
- package/src/modules/auth/AuthContext.tsx +9 -3
- package/src/modules/auth/ui/LoginModal.tsx +7 -2
- package/src/modules/communityTools/likedBy.ts +32 -0
- package/src/modules/communityTools/timeAgo.ts +16 -0
- package/src/modules/communityTools/ui/CardScreenshot.tsx +124 -0
- package/src/modules/communityTools/ui/CardTitleBlock.tsx +58 -0
- package/src/modules/communityTools/ui/CommunityPage.tsx +626 -0
- package/src/modules/communityTools/ui/FeedRow.tsx +310 -0
- package/src/modules/communityTools/ui/FeedSortControl.tsx +97 -0
- package/src/modules/communityTools/ui/LifecycleBadge.tsx +44 -0
- package/src/modules/communityTools/ui/LikeButton.tsx +56 -0
- package/src/modules/communityTools/ui/MarginPreview.tsx +143 -0
- package/src/modules/communityTools/ui/MyToolsShelf.tsx +112 -0
- package/src/modules/communityTools/ui/OwnerPicker.tsx +311 -0
- package/src/modules/communityTools/ui/PinButton.tsx +87 -0
- package/src/modules/communityTools/ui/ShelfTile.tsx +83 -0
- package/src/modules/communityTools/ui/TagPicker.tsx +118 -0
- package/src/modules/communityTools/ui/TagRow.tsx +118 -0
- package/src/modules/communityTools/ui/Toast.tsx +105 -0
- package/src/modules/communityTools/ui/ToolCard.tsx +519 -0
- package/src/modules/communityTools/ui/ToolFormDialog.tsx +922 -0
- package/src/modules/communityTools/ui/ToolSearch.tsx +111 -0
- package/src/modules/communityTools/useCommunityTools.ts +146 -0
- package/src/modules/communityTools/useCommunityToolsConfig.ts +26 -0
- package/src/modules/communityTools/useTimeUp.ts +14 -0
- package/src/routeTree.gen.ts +52 -0
- package/src/routes/_layout/community.$slug.tsx +7 -0
- package/src/routes/_layout/community.tsx +97 -0
- package/src/ui/components/header/Header.tsx +9 -3
- package/src/util/highlightMatches.tsx +34 -0
- package/dist/esm/modules/appCatalog/ui/components/ViewToggle.d.ts +0 -12
- package/dist/esm/modules/appCatalog/ui/components/ViewToggle.js +0 -56
- package/dist/esm/modules/appCatalog/ui/components/ViewToggle.js.map +0 -1
- package/src/modules/appCatalog/ui/components/ViewToggle.tsx +0 -59
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Camera, ImageOff, ExternalLink, Maximize2 } from "lucide-react";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { ScreenshotGallery } from "../../appCatalog/ui/components/ScreenshotGallery.js";
|
|
5
|
+
import { cn } from "../../../lib/utils.js";
|
|
6
|
+
import { screenshotUrl } from "./FeedRow.js";
|
|
7
|
+
const BOX = "relative flex aspect-[16/10] max-h-[320px] w-full items-center justify-center overflow-hidden rounded-[14px] border border-border bg-muted shadow-sm";
|
|
8
|
+
function formatCardDate(iso) {
|
|
9
|
+
return new Date(iso).toLocaleDateString("en-GB", {
|
|
10
|
+
day: "numeric",
|
|
11
|
+
month: "short",
|
|
12
|
+
year: "numeric"
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function CardScreenshot({
|
|
16
|
+
tool,
|
|
17
|
+
capturing
|
|
18
|
+
}) {
|
|
19
|
+
const [open, setOpen] = useState(false);
|
|
20
|
+
const { screenshotId, capturedAt } = tool;
|
|
21
|
+
if (!screenshotId) {
|
|
22
|
+
return /* @__PURE__ */ jsxs("figure", { "data-testid": "card-screenshot", className: "mt-[22px]", children: [
|
|
23
|
+
/* @__PURE__ */ jsx(
|
|
24
|
+
"div",
|
|
25
|
+
{
|
|
26
|
+
"data-testid": "card-screenshot-box",
|
|
27
|
+
"data-state": capturing ? "capturing" : "missing",
|
|
28
|
+
"aria-busy": capturing || void 0,
|
|
29
|
+
className: cn(
|
|
30
|
+
BOX,
|
|
31
|
+
"flex-col gap-2.5 px-6 text-center text-sm font-semibold text-muted-foreground"
|
|
32
|
+
),
|
|
33
|
+
children: capturing ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
34
|
+
/* @__PURE__ */ jsx(Camera, { "aria-hidden": "true", className: "size-7 animate-pulse" }),
|
|
35
|
+
"Taking a screenshot of the site…"
|
|
36
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
37
|
+
/* @__PURE__ */ jsx(ImageOff, { "aria-hidden": "true", className: "size-7" }),
|
|
38
|
+
"No screenshot. The site may need a login, or it did not load."
|
|
39
|
+
] })
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ jsx("figcaption", { className: "mt-2 text-[12.5px] font-semibold text-muted-foreground", children: capturing ? "Usually under a minute" : "Open the site to see it" })
|
|
43
|
+
] });
|
|
44
|
+
}
|
|
45
|
+
return /* @__PURE__ */ jsxs("figure", { "data-testid": "card-screenshot", className: "mt-[22px]", children: [
|
|
46
|
+
/* @__PURE__ */ jsxs(
|
|
47
|
+
"div",
|
|
48
|
+
{
|
|
49
|
+
"data-testid": "card-screenshot-box",
|
|
50
|
+
"data-state": "captured",
|
|
51
|
+
className: BOX,
|
|
52
|
+
children: [
|
|
53
|
+
/* @__PURE__ */ jsxs(
|
|
54
|
+
"a",
|
|
55
|
+
{
|
|
56
|
+
href: tool.url,
|
|
57
|
+
target: "_blank",
|
|
58
|
+
rel: "noopener noreferrer",
|
|
59
|
+
"aria-label": `Open ${tool.name} in a new tab`,
|
|
60
|
+
"data-testid": "card-screenshot-link",
|
|
61
|
+
className: "group/shot block size-full rounded-[14px] focus-visible:outline-2 focus-visible:-outline-offset-4 focus-visible:outline-ring",
|
|
62
|
+
children: [
|
|
63
|
+
/* @__PURE__ */ jsx(
|
|
64
|
+
"img",
|
|
65
|
+
{
|
|
66
|
+
src: screenshotUrl(screenshotId, 1280),
|
|
67
|
+
alt: `Screenshot of ${tool.name}`,
|
|
68
|
+
className: "size-full object-cover object-left-top"
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 flex items-center justify-center bg-black/0 transition-colors group-focus-visible/shot:bg-black/20 group-hover/shot:bg-black/20", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-lg bg-primary px-3.5 py-2 text-sm font-extrabold text-primary-foreground opacity-0 shadow-sm transition-opacity group-focus-visible/shot:opacity-100 group-hover/shot:opacity-100", children: [
|
|
72
|
+
"Open site",
|
|
73
|
+
/* @__PURE__ */ jsx(ExternalLink, { "aria-hidden": "true", className: "size-4" })
|
|
74
|
+
] }) })
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
),
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
"button",
|
|
80
|
+
{
|
|
81
|
+
type: "button",
|
|
82
|
+
"aria-label": `Enlarge screenshot of ${tool.name}`,
|
|
83
|
+
title: "Enlarge",
|
|
84
|
+
onClick: () => setOpen(true),
|
|
85
|
+
className: "absolute top-3 right-3 inline-flex size-8 items-center justify-center rounded-lg bg-black/65 text-white hover:bg-black/80 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
|
|
86
|
+
children: /* @__PURE__ */ jsx(Maximize2, { "aria-hidden": "true", className: "size-4" })
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
capturedAt && /* @__PURE__ */ jsxs("figcaption", { className: "mt-2 text-[12.5px] font-semibold text-muted-foreground", children: [
|
|
93
|
+
"Screenshot captured ",
|
|
94
|
+
formatCardDate(capturedAt)
|
|
95
|
+
] }),
|
|
96
|
+
/* @__PURE__ */ jsx(
|
|
97
|
+
ScreenshotGallery,
|
|
98
|
+
{
|
|
99
|
+
app: { displayName: tool.name },
|
|
100
|
+
screenshotIds: [screenshotId],
|
|
101
|
+
open,
|
|
102
|
+
onOpenChange: setOpen,
|
|
103
|
+
title: `${tool.name} screenshot`
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
] });
|
|
107
|
+
}
|
|
108
|
+
export {
|
|
109
|
+
CardScreenshot,
|
|
110
|
+
formatCardDate
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=CardScreenshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CardScreenshot.js","sources":["../../../../../src/modules/communityTools/ui/CardScreenshot.tsx"],"sourcesContent":["import type { CommunityTool } from '@igstack/app-catalog-shared-core'\nimport { Camera, ExternalLink, ImageOff, Maximize2 } from 'lucide-react'\nimport { useState } from 'react'\nimport { ScreenshotGallery } from '~/modules/appCatalog/ui/components/ScreenshotGallery'\nimport { cn } from '~/lib/utils'\nimport { screenshotUrl } from './FeedRow'\n\n/**\n * The 16:10 box every state shares, so swapping one for another moves nothing.\n * Capped in height, so how to use it and who to ask stay above the fold; the\n * top of the page, where its title is, is what shows.\n */\nconst BOX =\n 'relative flex aspect-[16/10] max-h-[320px] w-full items-center justify-center overflow-hidden rounded-[14px] border border-border bg-muted shadow-sm'\n\nexport function formatCardDate(iso: string): string {\n return new Date(iso).toLocaleDateString('en-GB', {\n day: 'numeric',\n month: 'short',\n year: 'numeric',\n })\n}\n\n/**\n * The tool's screenshot, full width: a click opens the site, like the title\n * block, and the corner button enlarges it in the screenshot viewer. A tool\n * with none yet shows a placeholder in the same box, not a link: \"still\n * capturing\" while its first visit is to come, otherwise \"no screenshot\".\n */\nexport function CardScreenshot({\n tool,\n capturing,\n}: {\n tool: CommunityTool\n /** A first screenshot is on its way and still worth waiting for. */\n capturing: boolean\n}) {\n const [open, setOpen] = useState(false)\n const { screenshotId, capturedAt } = tool\n\n if (!screenshotId) {\n return (\n <figure data-testid=\"card-screenshot\" className=\"mt-[22px]\">\n <div\n data-testid=\"card-screenshot-box\"\n data-state={capturing ? 'capturing' : 'missing'}\n aria-busy={capturing || undefined}\n className={cn(\n BOX,\n 'flex-col gap-2.5 px-6 text-center text-sm font-semibold text-muted-foreground',\n )}\n >\n {capturing ? (\n <>\n <Camera aria-hidden=\"true\" className=\"size-7 animate-pulse\" />\n Taking a screenshot of the site…\n </>\n ) : (\n <>\n <ImageOff aria-hidden=\"true\" className=\"size-7\" />\n No screenshot. The site may need a login, or it did not load.\n </>\n )}\n </div>\n <figcaption className=\"mt-2 text-[12.5px] font-semibold text-muted-foreground\">\n {capturing ? 'Usually under a minute' : 'Open the site to see it'}\n </figcaption>\n </figure>\n )\n }\n\n return (\n <figure data-testid=\"card-screenshot\" className=\"mt-[22px]\">\n <div\n data-testid=\"card-screenshot-box\"\n data-state=\"captured\"\n className={BOX}\n >\n <a\n href={tool.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={`Open ${tool.name} in a new tab`}\n data-testid=\"card-screenshot-link\"\n className=\"group/shot block size-full rounded-[14px] focus-visible:outline-2 focus-visible:-outline-offset-4 focus-visible:outline-ring\"\n >\n <img\n src={screenshotUrl(screenshotId, 1280)}\n alt={`Screenshot of ${tool.name}`}\n className=\"size-full object-cover object-left-top\"\n />\n <span className=\"absolute inset-0 flex items-center justify-center bg-black/0 transition-colors group-focus-visible/shot:bg-black/20 group-hover/shot:bg-black/20\">\n <span className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3.5 py-2 text-sm font-extrabold text-primary-foreground opacity-0 shadow-sm transition-opacity group-focus-visible/shot:opacity-100 group-hover/shot:opacity-100\">\n Open site\n <ExternalLink aria-hidden=\"true\" className=\"size-4\" />\n </span>\n </span>\n </a>\n {/* Beside the link, not in it: enlarging never opens the site. */}\n <button\n type=\"button\"\n aria-label={`Enlarge screenshot of ${tool.name}`}\n title=\"Enlarge\"\n onClick={() => setOpen(true)}\n className=\"absolute top-3 right-3 inline-flex size-8 items-center justify-center rounded-lg bg-black/65 text-white hover:bg-black/80 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n >\n <Maximize2 aria-hidden=\"true\" className=\"size-4\" />\n </button>\n </div>\n {capturedAt && (\n <figcaption className=\"mt-2 text-[12.5px] font-semibold text-muted-foreground\">\n Screenshot captured {formatCardDate(capturedAt)}\n </figcaption>\n )}\n <ScreenshotGallery\n app={{ displayName: tool.name }}\n screenshotIds={[screenshotId]}\n open={open}\n onOpenChange={setOpen}\n title={`${tool.name} screenshot`}\n />\n </figure>\n )\n}\n"],"names":[],"mappings":";;;;;;AAYA,MAAM,MACJ;AAEK,SAAS,eAAe,KAAqB;AAClD,SAAO,IAAI,KAAK,GAAG,EAAE,mBAAmB,SAAS;AAAA,IAC/C,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,EAAA,CACP;AACH;AAQO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AACF,GAIG;AACD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,EAAE,cAAc,WAAA,IAAe;AAErC,MAAI,CAAC,cAAc;AACjB,WACE,qBAAC,UAAA,EAAO,eAAY,mBAAkB,WAAU,aAC9C,UAAA;AAAA,MAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,eAAY;AAAA,UACZ,cAAY,YAAY,cAAc;AAAA,UACtC,aAAW,aAAa;AAAA,UACxB,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UAAA;AAAA,UAGD,sBACC,qBAAA,UAAA,EACE,UAAA;AAAA,YAAA,oBAAC,QAAA,EAAO,eAAY,QAAO,WAAU,wBAAuB;AAAA,YAAE;AAAA,UAAA,EAAA,CAEhE,IAEA,qBAAA,UAAA,EACE,UAAA;AAAA,YAAA,oBAAC,UAAA,EAAS,eAAY,QAAO,WAAU,UAAS;AAAA,YAAE;AAAA,UAAA,EAAA,CAEpD;AAAA,QAAA;AAAA,MAAA;AAAA,0BAGH,cAAA,EAAW,WAAU,0DACnB,UAAA,YAAY,2BAA2B,0BAAA,CAC1C;AAAA,IAAA,GACF;AAAA,EAEJ;AAEA,SACE,qBAAC,UAAA,EAAO,eAAY,mBAAkB,WAAU,aAC9C,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,eAAY;AAAA,QACZ,cAAW;AAAA,QACX,WAAW;AAAA,QAEX,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM,KAAK;AAAA,cACX,QAAO;AAAA,cACP,KAAI;AAAA,cACJ,cAAY,QAAQ,KAAK,IAAI;AAAA,cAC7B,eAAY;AAAA,cACZ,WAAU;AAAA,cAEV,UAAA;AAAA,gBAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,KAAK,cAAc,cAAc,IAAI;AAAA,oBACrC,KAAK,iBAAiB,KAAK,IAAI;AAAA,oBAC/B,WAAU;AAAA,kBAAA;AAAA,gBAAA;AAAA,oCAEX,QAAA,EAAK,WAAU,oJACd,UAAA,qBAAC,QAAA,EAAK,WAAU,8NAA6N,UAAA;AAAA,kBAAA;AAAA,kBAE3O,oBAAC,cAAA,EAAa,eAAY,QAAO,WAAU,SAAA,CAAS;AAAA,gBAAA,EAAA,CACtD,EAAA,CACF;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,UAGF;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,cAAY,yBAAyB,KAAK,IAAI;AAAA,cAC9C,OAAM;AAAA,cACN,SAAS,MAAM,QAAQ,IAAI;AAAA,cAC3B,WAAU;AAAA,cAEV,UAAA,oBAAC,WAAA,EAAU,eAAY,QAAO,WAAU,SAAA,CAAS;AAAA,YAAA;AAAA,UAAA;AAAA,QACnD;AAAA,MAAA;AAAA,IAAA;AAAA,IAED,cACC,qBAAC,cAAA,EAAW,WAAU,0DAAyD,UAAA;AAAA,MAAA;AAAA,MACxD,eAAe,UAAU;AAAA,IAAA,GAChD;AAAA,IAEF;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK,EAAE,aAAa,KAAK,KAAA;AAAA,QACzB,eAAe,CAAC,YAAY;AAAA,QAC5B;AAAA,QACA,cAAc;AAAA,QACd,OAAO,GAAG,KAAK,IAAI;AAAA,MAAA;AAAA,IAAA;AAAA,EACrB,GACF;AAEJ;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CommunityTool } from '@igstack/app-catalog-shared-core';
|
|
2
|
+
/**
|
|
3
|
+
* The card's door: favicon (a globe when the site has none), name, badges and
|
|
4
|
+
* address, all one link that opens the site in a new tab.
|
|
5
|
+
*/
|
|
6
|
+
export declare function CardTitleBlock({ tool }: {
|
|
7
|
+
tool: CommunityTool;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Globe, ExternalLink } from "lucide-react";
|
|
3
|
+
import { cn } from "../../../lib/utils.js";
|
|
4
|
+
import { screenshotUrl } from "./FeedRow.js";
|
|
5
|
+
import { LifecycleBadge, UnreviewedBadge } from "./LifecycleBadge.js";
|
|
6
|
+
function CardTitleBlock({ tool }) {
|
|
7
|
+
const archived = tool.lifecycle.state === "archived";
|
|
8
|
+
return /* @__PURE__ */ jsxs(
|
|
9
|
+
"a",
|
|
10
|
+
{
|
|
11
|
+
href: tool.url,
|
|
12
|
+
target: "_blank",
|
|
13
|
+
rel: "noopener noreferrer",
|
|
14
|
+
"data-testid": "card-title-block",
|
|
15
|
+
className: cn(
|
|
16
|
+
"group/door inline-flex min-w-0 items-center gap-[15px] rounded-[14px] border border-border bg-primary/[0.025] px-[17px] py-[11px] transition-colors",
|
|
17
|
+
"hover:border-primary/40 hover:bg-primary/[0.07] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
|
|
18
|
+
archived && "opacity-70 grayscale"
|
|
19
|
+
),
|
|
20
|
+
children: [
|
|
21
|
+
/* @__PURE__ */ jsx("span", { className: "inline-flex size-12 shrink-0 items-center justify-center overflow-hidden rounded-xl border border-border bg-card text-muted-foreground", children: tool.faviconId ? /* @__PURE__ */ jsx(
|
|
22
|
+
"img",
|
|
23
|
+
{
|
|
24
|
+
src: screenshotUrl(tool.faviconId, 64),
|
|
25
|
+
alt: "",
|
|
26
|
+
className: "size-7"
|
|
27
|
+
}
|
|
28
|
+
) : /* @__PURE__ */ jsx(Globe, { "aria-hidden": "true", className: "size-6", strokeWidth: 1.75 }) }),
|
|
29
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
30
|
+
/* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-center gap-x-3 gap-y-1", children: [
|
|
31
|
+
/* @__PURE__ */ jsx(
|
|
32
|
+
"span",
|
|
33
|
+
{
|
|
34
|
+
"data-testid": "card-tool-name",
|
|
35
|
+
className: "font-serif text-[26px] leading-tight font-semibold",
|
|
36
|
+
children: tool.name
|
|
37
|
+
}
|
|
38
|
+
),
|
|
39
|
+
/* @__PURE__ */ jsx(LifecycleBadge, { lifecycle: tool.lifecycle }),
|
|
40
|
+
!tool.reviewed && /* @__PURE__ */ jsx(UnreviewedBadge, {})
|
|
41
|
+
] }),
|
|
42
|
+
/* @__PURE__ */ jsx("span", { className: "truncate font-mono text-[13px] text-muted-foreground", children: tool.host }),
|
|
43
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "(opens in a new tab)" })
|
|
44
|
+
] }),
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
ExternalLink,
|
|
47
|
+
{
|
|
48
|
+
"aria-hidden": "true",
|
|
49
|
+
className: "size-[18px] shrink-0 self-start text-muted-foreground group-hover/door:text-primary"
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
CardTitleBlock
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=CardTitleBlock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CardTitleBlock.js","sources":["../../../../../src/modules/communityTools/ui/CardTitleBlock.tsx"],"sourcesContent":["import type { CommunityTool } from '@igstack/app-catalog-shared-core'\nimport { ExternalLink, Globe } from 'lucide-react'\nimport { cn } from '~/lib/utils'\nimport { screenshotUrl } from './FeedRow'\nimport { LifecycleBadge, UnreviewedBadge } from './LifecycleBadge'\n\n/**\n * The card's door: favicon (a globe when the site has none), name, badges and\n * address, all one link that opens the site in a new tab.\n */\nexport function CardTitleBlock({ tool }: { tool: CommunityTool }) {\n const archived = tool.lifecycle.state === 'archived'\n return (\n <a\n href={tool.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-testid=\"card-title-block\"\n className={cn(\n 'group/door inline-flex min-w-0 items-center gap-[15px] rounded-[14px] border border-border bg-primary/[0.025] px-[17px] py-[11px] transition-colors',\n 'hover:border-primary/40 hover:bg-primary/[0.07] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n archived && 'opacity-70 grayscale',\n )}\n >\n <span className=\"inline-flex size-12 shrink-0 items-center justify-center overflow-hidden rounded-xl border border-border bg-card text-muted-foreground\">\n {tool.faviconId ? (\n <img\n src={screenshotUrl(tool.faviconId, 64)}\n alt=\"\"\n className=\"size-7\"\n />\n ) : (\n <Globe aria-hidden=\"true\" className=\"size-6\" strokeWidth={1.75} />\n )}\n </span>\n <span className=\"flex min-w-0 flex-col gap-0.5\">\n <span className=\"flex flex-wrap items-center gap-x-3 gap-y-1\">\n <span\n data-testid=\"card-tool-name\"\n className=\"font-serif text-[26px] leading-tight font-semibold\"\n >\n {tool.name}\n </span>\n <LifecycleBadge lifecycle={tool.lifecycle} />\n {!tool.reviewed && <UnreviewedBadge />}\n </span>\n <span className=\"truncate font-mono text-[13px] text-muted-foreground\">\n {tool.host}\n </span>\n <span className=\"sr-only\">(opens in a new tab)</span>\n </span>\n <ExternalLink\n aria-hidden=\"true\"\n className=\"size-[18px] shrink-0 self-start text-muted-foreground group-hover/door:text-primary\"\n />\n </a>\n )\n}\n"],"names":[],"mappings":";;;;;AAUO,SAAS,eAAe,EAAE,QAAiC;AAChE,QAAM,WAAW,KAAK,UAAU,UAAU;AAC1C,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAM,KAAK;AAAA,MACX,QAAO;AAAA,MACP,KAAI;AAAA,MACJ,eAAY;AAAA,MACZ,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,YAAY;AAAA,MAAA;AAAA,MAGd,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,0IACb,UAAA,KAAK,YACJ;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAK,cAAc,KAAK,WAAW,EAAE;AAAA,YACrC,KAAI;AAAA,YACJ,WAAU;AAAA,UAAA;AAAA,QAAA,wBAGX,OAAA,EAAM,eAAY,QAAO,WAAU,UAAS,aAAa,KAAA,CAAM,GAEpE;AAAA,QACA,qBAAC,QAAA,EAAK,WAAU,iCACd,UAAA;AAAA,UAAA,qBAAC,QAAA,EAAK,WAAU,+CACd,UAAA;AAAA,YAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,eAAY;AAAA,gBACZ,WAAU;AAAA,gBAET,UAAA,KAAK;AAAA,cAAA;AAAA,YAAA;AAAA,YAER,oBAAC,gBAAA,EAAe,WAAW,KAAK,UAAA,CAAW;AAAA,YAC1C,CAAC,KAAK,YAAY,oBAAC,iBAAA,CAAA,CAAgB;AAAA,UAAA,GACtC;AAAA,UACA,oBAAC,QAAA,EAAK,WAAU,wDACb,eAAK,MACR;AAAA,UACA,oBAAC,QAAA,EAAK,WAAU,WAAU,UAAA,uBAAA,CAAoB;AAAA,QAAA,GAChD;AAAA,QACA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ;AAAA,IAAA;AAAA,EAAA;AAGN;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FeedSort, SortDir } from '@igstack/app-catalog-shared-core';
|
|
2
|
+
export interface CommunityPageProps {
|
|
3
|
+
/** `?tag=`: `<kind>:<value>`, or none for the whole feed. */
|
|
4
|
+
tag: string | undefined;
|
|
5
|
+
sort: FeedSort;
|
|
6
|
+
dir: SortDir;
|
|
7
|
+
onTagChange: (tag: string | undefined) => void;
|
|
8
|
+
onSortChange: (sort: FeedSort, dir: SortDir) => void;
|
|
9
|
+
/** The tool whose card is open over the page (`/community/<slug>`). */
|
|
10
|
+
cardSlug?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function CommunityPage({ tag, sort, dir, onTagChange, onSortChange, cardSlug, }: CommunityPageProps): import("react/jsx-runtime").JSX.Element;
|