From 9a7e83dee82048190de80b4713a867d22bdc648e Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sat, 25 Apr 2026 16:29:03 +0000 Subject: [PATCH 1/2] Remove starter templates, add welcome screen with guide and social links --- apps/builder/app/dashboard/dashboard.test.ts | 32 ++--- apps/builder/app/dashboard/dashboard.tsx | 85 ++++++------- .../app/dashboard/projects/projects.tsx | 11 ++ .../app/dashboard/search/search-results.tsx | 24 +--- apps/builder/app/dashboard/shared/types.ts | 1 - .../app/dashboard/templates/template-card.tsx | 60 --------- .../app/dashboard/templates/templates.tsx | 72 ----------- .../builder/app/dashboard/welcome/welcome.tsx | 120 ++++++++++++++---- apps/builder/app/env/env.server.ts | 12 -- .../app/routes/_ui.dashboard.templates.tsx | 27 ---- apps/builder/app/routes/_ui.dashboard.tsx | 10 -- apps/builder/app/shared/help.tsx | 29 ++++- packages/dashboard/src/db/projects.ts | 19 +-- packages/icons/icons/bluesky.svg | 12 ++ packages/icons/icons/facebook.svg | 12 ++ packages/icons/icons/linkedin.svg | 12 ++ packages/icons/icons/reddit.svg | 14 ++ .../icons/src/__generated__/components.tsx | 90 +++++++++++++ packages/icons/src/__generated__/svg.ts | 8 ++ 19 files changed, 343 insertions(+), 307 deletions(-) delete mode 100644 apps/builder/app/dashboard/templates/template-card.tsx delete mode 100644 apps/builder/app/dashboard/templates/templates.tsx delete mode 100644 apps/builder/app/routes/_ui.dashboard.templates.tsx create mode 100644 packages/icons/icons/bluesky.svg create mode 100644 packages/icons/icons/facebook.svg create mode 100644 packages/icons/icons/linkedin.svg create mode 100644 packages/icons/icons/reddit.svg diff --git a/apps/builder/app/dashboard/dashboard.test.ts b/apps/builder/app/dashboard/dashboard.test.ts index bf8f80aa39f3..54a7f98082e6 100644 --- a/apps/builder/app/dashboard/dashboard.test.ts +++ b/apps/builder/app/dashboard/dashboard.test.ts @@ -5,38 +5,24 @@ const { getView } = __testing__; describe("getView", () => { test("returns 'search' for search path", () => { - expect(getView("/dashboard/search", true, true)).toBe("search"); - expect(getView("/dashboard/search", false, true)).toBe("search"); + expect(getView("/dashboard/search", true, false)).toBe("search"); + expect(getView("/dashboard/search", false, false)).toBe("search"); }); - test("returns 'welcome' when no projects on default workspace", () => { - expect(getView("/dashboard", false, true)).toBe("welcome"); - expect(getView("/dashboard/templates", false, true)).toBe("welcome"); + test("returns 'welcome' when no projects and workspace not suspended", () => { + expect(getView("/dashboard", false, false)).toBe("welcome"); }); - test("returns 'projects' when no projects on non-default workspace", () => { - // Non-default workspaces should never show the welcome onboarding page - expect(getView("/dashboard", false, false)).toBe("projects"); + test("returns 'projects' when workspace is suspended with no projects", () => { + expect(getView("/dashboard", false, true)).toBe("projects"); }); - test("returns 'templates' on non-default workspace with no projects", () => { - expect(getView("/dashboard/templates", false, false)).toBe("templates"); - }); - - test("returns 'templates' for templates path with projects", () => { - expect(getView("/dashboard/templates", true, true)).toBe("templates"); - }); - - test("returns 'projects' for dashboard root with projects", () => { + test("returns 'projects' when there are projects", () => { + expect(getView("/dashboard", true, false)).toBe("projects"); expect(getView("/dashboard", true, true)).toBe("projects"); }); test("returns 'projects' for unknown paths with projects", () => { - expect(getView("/dashboard/unknown", true, true)).toBe("projects"); - }); - - test("search takes priority over welcome", () => { - // Even with no projects, search view should show - expect(getView("/dashboard/search", false, true)).toBe("search"); + expect(getView("/dashboard/unknown", true, false)).toBe("projects"); }); }); diff --git a/apps/builder/app/dashboard/dashboard.tsx b/apps/builder/app/dashboard/dashboard.tsx index 02c882f27f63..29beb5d1099e 100644 --- a/apps/builder/app/dashboard/dashboard.tsx +++ b/apps/builder/app/dashboard/dashboard.tsx @@ -17,7 +17,7 @@ import { Grid, IconButton, } from "@webstudio-is/design-system"; -import { BodyIcon, ExtensionIcon } from "@webstudio-is/icons"; +import { BodyIcon } from "@webstudio-is/icons"; import { NavLink, useLocation, @@ -33,10 +33,9 @@ import { dashboardPath } from "~/shared/router-utils"; import { CollapsibleSection } from "~/builder/shared/collapsible-section"; import { ProfileMenu } from "./profile-menu"; import { Projects } from "./projects/projects"; -import { Templates } from "./templates/templates"; import { Welcome } from "./welcome/welcome"; import { Header } from "./shared/layout"; -import { help } from "~/shared/help"; +import { help, socialLinks } from "~/shared/help"; import { SearchResults } from "./search/search-results"; import type { DashboardData } from "./shared/types"; import { Search } from "./search/search-field"; @@ -194,22 +193,16 @@ export const DashboardSetup = ({ data }: { data: DashboardData }) => { const getView = ( pathname: string, hasProjects: boolean, - isDefaultWorkspace: boolean + isWorkspaceSuspended: boolean ) => { if (pathname === dashboardPath("search")) { return "search"; } - // Only show the onboarding welcome page on the default workspace - // when the user has no projects yet. Non-default workspaces that are - // empty should show the normal (empty) projects view. - if (hasProjects === false && isDefaultWorkspace) { + if (hasProjects === false && isWorkspaceSuspended === false) { return "welcome"; } - if (pathname === dashboardPath("templates")) { - return "templates"; - } return "projects"; }; @@ -229,7 +222,6 @@ export const Dashboard = () => { publisherHost, projectToClone, projects, - templates, workspaces, currentWorkspaceId, } = data; @@ -243,38 +235,21 @@ export const Dashboard = () => { } const isWorkspaceSuspended = isDowngradedForMember(currentWorkspace); - const hasProjects = projects.length > 0 || isWorkspaceSuspended; - const isDefaultWorkspace = - currentWorkspaceId === undefined || - workspaces?.find((w) => w.id === currentWorkspaceId)?.isDefault === true; - const view = getView(location.pathname, hasProjects, isDefaultWorkspace); + const hasProjects = projects.length > 0; + const view = getView(location.pathname, hasProjects, isWorkspaceSuspended); const showWorkspaceSelector = workspaces !== undefined && workspaces.length > 0 && currentWorkspaceId !== undefined; - const navItems = - view === "welcome" - ? [ - { - to: dashboardPath(), - prefix: , - children: "Welcome", - }, - ] - : [ - { - to: dashboardPath("projects"), - prefix: , - children: "Projects", - }, - { - to: dashboardPath("templates"), - prefix: , - children: "Starter templates", - }, - ]; + const navItems = [ + { + to: dashboardPath("projects"), + prefix: , + children: "Projects", + }, + ]; return ( @@ -360,6 +335,29 @@ export const Dashboard = () => { children: item.label, }))} /> + + + Follow us: + + {socialLinks.map(({ label, url, icon }) => ( + + {icon} + + ))} + {view === "projects" && ( @@ -372,17 +370,8 @@ export const Dashboard = () => { isWorkspaceSuspended={isWorkspaceSuspended} /> )} - {view === "templates" && ( - - )} {view === "welcome" && ( - + )} {view === "search" && } diff --git a/apps/builder/app/dashboard/projects/projects.tsx b/apps/builder/app/dashboard/projects/projects.tsx index 83d2c65b2c85..37025d3a9bd5 100644 --- a/apps/builder/app/dashboard/projects/projects.tsx +++ b/apps/builder/app/dashboard/projects/projects.tsx @@ -10,6 +10,8 @@ import { ToggleGroupButton, PanelBanner, panelBannerIconColor, + Link, + buttonStyle, } from "@webstudio-is/design-system"; import { RepeatGridIcon, ListViewIcon } from "@webstudio-is/icons"; import type { DashboardProject } from "@webstudio-is/dashboard"; @@ -145,6 +147,15 @@ export const Projects = (props: ProjectsProps) => { + + Use template + {permissions.canCreateProject && ( )} diff --git a/apps/builder/app/dashboard/search/search-results.tsx b/apps/builder/app/dashboard/search/search-results.tsx index 18ed6b8e3282..11315e61b6a3 100644 --- a/apps/builder/app/dashboard/search/search-results.tsx +++ b/apps/builder/app/dashboard/search/search-results.tsx @@ -1,42 +1,37 @@ import { useMemo } from "react"; import { matchSorter } from "match-sorter"; import { useSearchParams } from "react-router-dom"; -import { Flex, Separator, Text, theme } from "@webstudio-is/design-system"; +import { Flex, Text, theme } from "@webstudio-is/design-system"; import type { DashboardProject } from "@webstudio-is/dashboard"; import { ProjectsGrid } from "../projects/projects"; import { Header, Main } from "../shared/layout"; import type { DashboardData } from "../shared/types"; import { NothingFound } from "./nothing-found"; -import { TemplatesGrid } from "../templates/templates"; type SearchResults = { projects: Array; - templates: Array; }; const initialSearchResults: SearchResults = { - templates: [], projects: [], } as const; export const SearchResults = (props: DashboardData) => { const [searchParams] = useSearchParams(); - const { projects, templates, publisherHost } = props; + const { projects, publisherHost } = props; const search = searchParams.get("q"); const results = useMemo(() => { - if (!search || !projects || !templates) { + if (!search || !projects) { return initialSearchResults; } const keys = ["title", "domain"]; return { projects: matchSorter(projects, search, { keys }), - templates: matchSorter(templates, search, { keys }), }; - }, [projects, templates, search]); + }, [projects, search]); - const nothingFound = - results.projects.length === 0 && results.templates.length === 0; + const nothingFound = results.projects.length === 0; return (
@@ -66,15 +61,6 @@ export const SearchResults = (props: DashboardData) => { /> )} - {results.templates.length > 0 && ( - <> - - - Templates - - - - )}
); diff --git a/apps/builder/app/dashboard/shared/types.ts b/apps/builder/app/dashboard/shared/types.ts index 35890fedbb13..7c1e2dfa0992 100644 --- a/apps/builder/app/dashboard/shared/types.ts +++ b/apps/builder/app/dashboard/shared/types.ts @@ -7,7 +7,6 @@ import type { Notifications } from "~/shared/polly/types"; export type DashboardData = { user: User; projects: Array; - templates: Array; planFeatures: PlanFeatures; purchases: Array; publisherHost: string; diff --git a/apps/builder/app/dashboard/templates/template-card.tsx b/apps/builder/app/dashboard/templates/template-card.tsx deleted file mode 100644 index 5b29310e53ec..000000000000 --- a/apps/builder/app/dashboard/templates/template-card.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { useState } from "react"; -import { Flex, Text, theme } from "@webstudio-is/design-system"; -import type { DashboardProject } from "@webstudio-is/dashboard"; -import { builderUrl } from "~/shared/router-utils"; -import { Card, CardContent, CardFooter } from "../shared/card"; -import { ThumbnailWithAbbr, ThumbnailWithImage } from "../shared/thumbnail"; -import { CloneProjectDialog } from "~/shared/clone-project"; - -type TemplateCardProps = { - project: DashboardProject; -}; - -export const TemplateCard = ({ project, ...props }: TemplateCardProps) => { - const [isDuplicateDialogOpen, setIsDuplicateDialogOpen] = useState(false); - const { title, previewImageAsset } = project; - return ( - - - {previewImageAsset ? ( - { - setIsDuplicateDialogOpen(true); - }} - /> - ) : ( - { - setIsDuplicateDialogOpen(true); - }} - /> - )} - - - - - {title} - - - - { - window.location.href = builderUrl({ - origin: window.origin, - projectId: projectId, - }); - }} - /> - - ); -}; diff --git a/apps/builder/app/dashboard/templates/templates.tsx b/apps/builder/app/dashboard/templates/templates.tsx deleted file mode 100644 index e51f4114dcfd..000000000000 --- a/apps/builder/app/dashboard/templates/templates.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { - Flex, - Grid, - List, - ListItem, - Text, - rawTheme, - theme, -} from "@webstudio-is/design-system"; -import type { DashboardProject } from "@webstudio-is/dashboard"; -import { Header, Main } from "../shared/layout"; -import { CreateProject } from "../projects/project-dialogs"; -import { useStore } from "@nanostores/react"; -import { TemplateCard } from "./template-card"; -import { $permissions } from "~/shared/nano-states"; - -export const TemplatesGrid = ({ - projects, -}: { - projects: Array; -}) => { - return ( - - - {projects.map((project) => { - return ( - - - - ); - })} - - - ); -}; - -export const Templates = ({ - projects, - currentWorkspaceId, -}: { - projects: Array; - currentWorkspaceId?: string; -}) => { - const permissions = useStore($permissions); - return ( -
-
- - Starter templates - - {permissions.canCreateProject && ( - - - - )} -
- - - -
- ); -}; diff --git a/apps/builder/app/dashboard/welcome/welcome.tsx b/apps/builder/app/dashboard/welcome/welcome.tsx index 8c1da3c0a7cd..df798b7e7337 100644 --- a/apps/builder/app/dashboard/welcome/welcome.tsx +++ b/apps/builder/app/dashboard/welcome/welcome.tsx @@ -1,46 +1,122 @@ -import { Flex, Text, theme } from "@webstudio-is/design-system"; -import type { DashboardProject } from "@webstudio-is/dashboard"; +import { + Flex, + Text, + Link, + buttonStyle, + theme, +} from "@webstudio-is/design-system"; +import { + YoutubeIcon, + ContentIcon, + DiscordIcon, + XLogoIcon, + BlueskyIcon, + FacebookIcon, + RedditIcon, +} from "@webstudio-is/icons"; import { useStore } from "@nanostores/react"; -import { Header, Main } from "../shared/layout"; +import { Main, Header } from "../shared/layout"; import { CreateProject } from "../projects/project-dialogs"; -import { TemplatesGrid } from "../templates/templates"; import { $permissions } from "~/shared/nano-states"; +const guideItems = [ + { + icon: , + label: "Watch video tutorials", + href: "https://wstd.us/101", + }, + { + icon: , + label: "Read the docs", + href: "https://docs.webstudio.is/", + }, + { + icon: , + label: "Join the community on Discord", + href: "https://wstd.us/community", + }, +]; + +const socialItems = [ + { icon: , label: "X", href: "https://x.com/getwebstudio" }, + { + icon: , + label: "Bluesky", + href: "https://bsky.app/profile/webstudio.is", + }, + { + icon: , + label: "Facebook", + href: "https://www.facebook.com/getwebstudio1/", + }, + { + icon: , + label: "Reddit", + href: "https://www.reddit.com/r/webstudio/", + }, +]; + export const Welcome = ({ - projects, currentWorkspaceId, }: { - projects: Array; currentWorkspaceId?: string; }) => { const permissions = useStore($permissions); return (
-
- - - Welcome to Webstudio! - - -
- - - Start with a template - {permissions.canCreateProject ? " or" : ""} - + + Welcome! + + + + + Start from a template + {permissions.canCreateProject && ( )} - + + + {guideItems.map(({ icon, label, href }) => ( + + {icon} + + {label} + + + ))} + + Follow for updates on: + {socialItems.map(({ icon, label, href }) => ( + + {icon} + + ))} + +
); diff --git a/apps/builder/app/env/env.server.ts b/apps/builder/app/env/env.server.ts index 834d7a2eef56..1599cae10f3a 100644 --- a/apps/builder/app/env/env.server.ts +++ b/apps/builder/app/env/env.server.ts @@ -44,17 +44,6 @@ const envSchema = z.object({ ENTRI_APPLICATION_ID: z.string().default("webstudio"), ENTRI_SECRET: z.string().optional(), - // Projects as templates in dashboard (comma-separated IDs) - PROJECT_TEMPLATES: z - .string() - .default("") - .transform((val) => - val - .split(",") - .map((id) => id.trim()) - .filter(Boolean) - ), - PUBLISHER_HOST: z.string().default("wstd.work"), STAGING_USERNAME: z.string().default("admin"), @@ -114,7 +103,6 @@ const rawEnv = { RESIZE_ORIGIN: process.env.RESIZE_ORIGIN, ENTRI_APPLICATION_ID: process.env.ENTRI_APPLICATION_ID, ENTRI_SECRET: process.env.ENTRI_SECRET, - PROJECT_TEMPLATES: process.env.PROJECT_TEMPLATES, PUBLISHER_HOST: process.env.PUBLISHER_HOST, STAGING_USERNAME: process.env.STAGING_USERNAME, STAGING_PASSWORD: process.env.STAGING_PASSWORD, diff --git a/apps/builder/app/routes/_ui.dashboard.templates.tsx b/apps/builder/app/routes/_ui.dashboard.templates.tsx deleted file mode 100644 index 28568f1d55a3..000000000000 --- a/apps/builder/app/routes/_ui.dashboard.templates.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { lazy } from "react"; -import { type MetaFunction } from "@remix-run/react"; -import { ClientOnly } from "~/shared/client-only"; -export { ErrorBoundary } from "~/shared/error/error-boundary"; - -export const meta = () => { - const metas: ReturnType = []; - - metas.push({ title: "Webstudio Dashboard | Templates" }); - - return metas; -}; - -const Dashboard = lazy(async () => { - const { Dashboard } = await import("~/dashboard/index.client"); - return { default: Dashboard }; -}); - -const DashboardRoute = () => { - return ( - - - - ); -}; - -export default DashboardRoute; diff --git a/apps/builder/app/routes/_ui.dashboard.tsx b/apps/builder/app/routes/_ui.dashboard.tsx index a94d71a20200..76ab0be5edc0 100644 --- a/apps/builder/app/routes/_ui.dashboard.tsx +++ b/apps/builder/app/routes/_ui.dashboard.tsx @@ -23,7 +23,6 @@ import { notification as notificationApi } from "@webstudio-is/project/index.ser import type { Role } from "@webstudio-is/project"; import { parseBuilderUrl } from "@webstudio-is/http-client"; import { dashboardProjectRouter } from "@webstudio-is/dashboard/index.server"; -import { db as dashboardDb } from "@webstudio-is/dashboard/index.server"; import { builderUrl, isDashboard, loginPath } from "~/shared/router-utils"; import { getSetting, setSetting } from "~/builder/shared/client-settings"; import env from "~/env/env.server"; @@ -129,12 +128,6 @@ const loadDashboardData = async (request: Request) => { ? [] : await dashboardProjectCaller(context).findMany(findManyInput); - const templates = await dashboardDb.db.findManyByIds( - env.PROJECT_TEMPLATES, - context, - { skipApprovalCheck: true } - ); - const notifications = await notificationApi.list(context); return { @@ -144,7 +137,6 @@ const loadDashboardData = async (request: Request) => { planFeatures, purchases, projects, - templates, workspaces, currentWorkspaceId, role, @@ -198,7 +190,6 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { purchases, origin, projects, - templates, workspaces, currentWorkspaceId, role, @@ -210,7 +201,6 @@ export const loader = async ({ request }: LoaderFunctionArgs) => { return { user, projects, - templates, planFeatures, purchases, publisherHost: env.PUBLISHER_HOST, diff --git a/apps/builder/app/shared/help.tsx b/apps/builder/app/shared/help.tsx index 57b6a74ecf4c..4c3cee52ff5b 100644 --- a/apps/builder/app/shared/help.tsx +++ b/apps/builder/app/shared/help.tsx @@ -1,4 +1,31 @@ -import { ContentIcon, DiscordIcon, YoutubeIcon } from "@webstudio-is/icons"; +import { + ContentIcon, + DiscordIcon, + YoutubeIcon, + XLogoIcon, + BlueskyIcon, + FacebookIcon, + RedditIcon, +} from "@webstudio-is/icons"; + +export const socialLinks = [ + { label: "X", url: "https://x.com/getwebstudio", icon: }, + { + label: "Bluesky", + url: "https://bsky.app/profile/webstudio.is", + icon: , + }, + { + label: "Facebook", + url: "https://www.facebook.com/webstudiois", + icon: , + }, + { + label: "Reddit", + url: "https://www.reddit.com/r/webstudio/", + icon: , + }, +] as const; export const help = [ { diff --git a/packages/dashboard/src/db/projects.ts b/packages/dashboard/src/db/projects.ts index 06f7582fbd5f..7922c23e4314 100644 --- a/packages/dashboard/src/db/projects.ts +++ b/packages/dashboard/src/db/projects.ts @@ -213,8 +213,7 @@ export const countByUserId = async ({ export const findManyByIds = async ( projectIds: string[], - context: AppContext, - { skipApprovalCheck = false }: { skipApprovalCheck?: boolean } = {} + context: AppContext ) => { if (projectIds.length === 0) { return []; @@ -231,16 +230,12 @@ export const findManyByIds = async ( .in("id", projectIds) .eq("isDeleted", false); - // PROJECT_TEMPLATES IDs are admin-curated via env var and skip approval. - // Other callers require ownership or marketplace approval. - if (skipApprovalCheck === false) { - if (userId !== undefined) { - query = query.or( - `userId.eq.${userId},marketplaceApprovalStatus.eq.APPROVED` - ); - } else { - query = query.eq("marketplaceApprovalStatus", "APPROVED"); - } + if (userId !== undefined) { + query = query.or( + `userId.eq.${userId},marketplaceApprovalStatus.eq.APPROVED` + ); + } else { + query = query.eq("marketplaceApprovalStatus", "APPROVED"); } const data = await query diff --git a/packages/icons/icons/bluesky.svg b/packages/icons/icons/bluesky.svg new file mode 100644 index 000000000000..1688b226c682 --- /dev/null +++ b/packages/icons/icons/bluesky.svg @@ -0,0 +1,12 @@ + + + diff --git a/packages/icons/icons/facebook.svg b/packages/icons/icons/facebook.svg new file mode 100644 index 000000000000..81f07fe051e3 --- /dev/null +++ b/packages/icons/icons/facebook.svg @@ -0,0 +1,12 @@ + + + diff --git a/packages/icons/icons/linkedin.svg b/packages/icons/icons/linkedin.svg new file mode 100644 index 000000000000..d8b98357c775 --- /dev/null +++ b/packages/icons/icons/linkedin.svg @@ -0,0 +1,12 @@ + + + diff --git a/packages/icons/icons/reddit.svg b/packages/icons/icons/reddit.svg new file mode 100644 index 000000000000..3cfc4ebce335 --- /dev/null +++ b/packages/icons/icons/reddit.svg @@ -0,0 +1,14 @@ + + + diff --git a/packages/icons/src/__generated__/components.tsx b/packages/icons/src/__generated__/components.tsx index d9a6ee7dbec4..74b895fd105d 100644 --- a/packages/icons/src/__generated__/components.tsx +++ b/packages/icons/src/__generated__/components.tsx @@ -1171,6 +1171,28 @@ export const BlockquoteIcon: IconComponent = forwardRef( ); BlockquoteIcon.displayName = "BlockquoteIcon"; +export const BlueskyIcon: IconComponent = forwardRef( + ({ fill = "none", size = 16, ...props }, forwardedRef) => { + return ( + + + + ); + } +); +BlueskyIcon.displayName = "BlueskyIcon"; + export const BodyIcon: IconComponent = forwardRef( ({ fill = "none", size = 16, ...props }, forwardedRef) => { return ( @@ -2636,6 +2658,28 @@ export const EyedropperIcon: IconComponent = forwardRef( ); EyedropperIcon.displayName = "EyedropperIcon"; +export const FacebookIcon: IconComponent = forwardRef( + ({ fill = "none", size = 16, ...props }, forwardedRef) => { + return ( + + + + ); + } +); +FacebookIcon.displayName = "FacebookIcon"; + export const FolderIcon: IconComponent = forwardRef( ({ fill = "none", size = 16, ...props }, forwardedRef) => { return ( @@ -3439,6 +3483,28 @@ export const LinkIcon: IconComponent = forwardRef( ); LinkIcon.displayName = "LinkIcon"; +export const LinkedinIcon: IconComponent = forwardRef( + ({ fill = "none", size = 16, ...props }, forwardedRef) => { + return ( + + + + ); + } +); +LinkedinIcon.displayName = "LinkedinIcon"; + export const ListItemIcon: IconComponent = forwardRef( ({ fill = "none", size = 16, ...props }, forwardedRef) => { return ( @@ -4401,6 +4467,30 @@ export const RangeCoverIcon: IconComponent = forwardRef( ); RangeCoverIcon.displayName = "RangeCoverIcon"; +export const RedditIcon: IconComponent = forwardRef( + ({ fill = "none", size = 16, ...props }, forwardedRef) => { + return ( + + + + ); + } +); +RedditIcon.displayName = "RedditIcon"; + export const RefreshCcwIcon: IconComponent = forwardRef( ({ fill = "none", size = 16, ...props }, forwardedRef) => { return ( diff --git a/packages/icons/src/__generated__/svg.ts b/packages/icons/src/__generated__/svg.ts index 91b62917a0e9..4f369bd0b179 100644 --- a/packages/icons/src/__generated__/svg.ts +++ b/packages/icons/src/__generated__/svg.ts @@ -84,6 +84,8 @@ export const BellIcon = ``; +export const BlueskyIcon = ``; + export const BodyIcon = ``; export const BoldIcon = ``; @@ -198,6 +200,8 @@ export const EyeOpenIcon = ``; +export const FacebookIcon = ``; + export const FolderIcon = ``; export const FooterIcon = ``; @@ -256,6 +260,8 @@ export const Link2Icon = ``; +export const LinkedinIcon = ``; + export const ListItemIcon = ``; export const ListViewIcon = ``; @@ -326,6 +332,8 @@ export const RangeContainIcon = ``; +export const RedditIcon = ``; + export const RefreshCcwIcon = ``; export const RefreshIcon = ``; From 7832294fc7105df6fa2ad19c3fb9c8f2963423ea Mon Sep 17 00:00:00 2001 From: Oleg Isonen Date: Sat, 25 Apr 2026 18:39:11 +0100 Subject: [PATCH 2/2] Update welcome.tsx --- apps/builder/app/dashboard/welcome/welcome.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/apps/builder/app/dashboard/welcome/welcome.tsx b/apps/builder/app/dashboard/welcome/welcome.tsx index df798b7e7337..7ecd093236fe 100644 --- a/apps/builder/app/dashboard/welcome/welcome.tsx +++ b/apps/builder/app/dashboard/welcome/welcome.tsx @@ -1,10 +1,4 @@ -import { - Flex, - Text, - Link, - buttonStyle, - theme, -} from "@webstudio-is/design-system"; +import { Flex, Text, Link, buttonStyle } from "@webstudio-is/design-system"; import { YoutubeIcon, ContentIcon, @@ -15,7 +9,7 @@ import { RedditIcon, } from "@webstudio-is/icons"; import { useStore } from "@nanostores/react"; -import { Main, Header } from "../shared/layout"; +import { Main } from "../shared/layout"; import { CreateProject } from "../projects/project-dialogs"; import { $permissions } from "~/shared/nano-states";