+ {Search}
+ {projects === null ? (
+ <>
+
+ Loading projects...
+
+ >
+ ) : (
+ <>
+ {Object.keys(filteredProjects).length === 0 && (
+
+ {searchTerm
+ ? `No projects were found for your search query "${searchTerm}".`
+ : "Network issue: Couldn't fetch any projects, please try again later."}
+
+ )}
+ >
+ )}
+
({ projectId }))}
+ Item={({ projectId }) => (
+ }
+ props={{
+ project: filteredProjects[projectId],
+ setSelectedProjectId: setSelectedProjectId,
+ }}
+ />
+ )}
+ Layout={ProjectsGrid}
+ />
+
+);
diff --git a/apps/new/widget/page/projects/CatalogProjectCard.jsx b/apps/new/widget/page/projects/CatalogProjectCard.jsx
new file mode 100644
index 00000000..e26b3477
--- /dev/null
+++ b/apps/new/widget/page/projects/CatalogProjectCard.jsx
@@ -0,0 +1,102 @@
+const project = props.project;
+if (!project) {
+ return "No Project Passed";
+}
+
+const MAX_DESCRIPTION_LENGTH = 80;
+
+const Card = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ border-radius: 1rem;
+ background: #23242b;
+ color: white;
+ transition: all 300ms;
+ height: 100%;
+
+ &:hover {
+ transform: translateY(-0.5rem);
+ cursor: pointer;
+ }
+
+ .image {
+ height: 168px;
+ border-radius: 16px 16px 0px 0px;
+ object-fit: cover;
+ }
+
+ .info {
+ display: flex;
+ flex-direction: column;
+ padding: 16px 24px;
+ gap: 16px;
+ flex: 1;
+ }
+
+ .title {
+ font-size: 16px;
+ font-weight: 600;
+ width: 100%;
+ }
+
+ .description {
+ font-size: 14px;
+ font-weight: 400;
+ word-wrap: break-word;
+ }
+
+ .tags {
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+ }
+
+ .tag {
+ box-shadow: 0px -0.699999988079071px 0px rgba(123, 123, 123, 0.36) inset;
+ padding: 4px 8px;
+ border-radius: 4px;
+ border: 1px solid rgba(123, 123, 123, 0.36);
+ }
+`;
+
+const getImageSrc = (image) => {
+ const defaultImageUrl =
+ "https://ipfs.near.social/ipfs/bafkreih4i6kftb34wpdzcuvgafozxz6tk6u4f5kcr2gwvtvxikvwriteci";
+ if (!image) return defaultImageUrl;
+ const { url, ipfs_cid } = image;
+ if (ipfs_cid) {
+ return ipfsUrlFromCid(ipfs_cid);
+ } else if (url) {
+ return url;
+ }
+ return defaultImageUrl;
+};
+
+return (
+