From aa9efef5dceaa00a9ac6f7cd07c12b842989499c Mon Sep 17 00:00:00 2001 From: bystrol Date: Fri, 27 Mar 2026 17:48:20 +0100 Subject: [PATCH 1/4] Add ResourceTree component and related types for managing resources - Introduced ResourceTree and ResourceTreeData components to display built-in Medusa commerce modules and third-party integrations. - Added resource-tree-types for type definitions related to resources. - Updated mdx-components to include ResourceTreeData. - Created postcss.config.mjs for Tailwind CSS integration. - Modified next-env.d.ts to reference the correct routes type definition. - Enhanced documentation with a new Resources section in index.mdx and a dedicated resources index page. --- app/components/resources/ResourceTree.tsx | 130 ++++++++++++++++++ app/components/resources/ResourceTreeData.tsx | 87 ++++++++++++ .../resources/resource-tree-types.ts | 12 ++ content/medusajs/_meta.js | 1 + content/medusajs/index.mdx | 6 + content/medusajs/resources/index.mdx | 12 ++ mdx-components.js | 14 +- next-env.d.ts | 2 +- postcss.config.mjs | 5 + 9 files changed, 262 insertions(+), 7 deletions(-) create mode 100644 app/components/resources/ResourceTree.tsx create mode 100644 app/components/resources/ResourceTreeData.tsx create mode 100644 app/components/resources/resource-tree-types.ts create mode 100644 content/medusajs/resources/index.mdx create mode 100644 postcss.config.mjs diff --git a/app/components/resources/ResourceTree.tsx b/app/components/resources/ResourceTree.tsx new file mode 100644 index 0000000..043aab1 --- /dev/null +++ b/app/components/resources/ResourceTree.tsx @@ -0,0 +1,130 @@ +"use client"; + +import { useState } from "react"; +import type { ResourceCategory, Status } from "./resource-tree-types"; + +const STATUS_CONFIG: Record = { + "built-in": { + label: "Built-in", + classes: + "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200", + }, + plugin: { + label: "Plugin", + classes: "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200", + }, +}; + +function StatusBadge({ status }: { status: Status }) { + const config = STATUS_CONFIG[status]; + return ( + + {config.label} + + ); +} + +function ChevronIcon({ open }: { open: boolean }) { + return ( + + + + ); +} + +export function ResourceTree({ data }: { data: ResourceCategory[] }) { + const [openCategories, setOpenCategories] = useState>( + () => new Set() + ); + + function toggle(category: string) { + setOpenCategories((prev) => { + const next = new Set(prev); + if (next.has(category)) { + next.delete(category); + } else { + next.add(category); + } + return next; + }); + } + + return ( +
+
+ {Object.values(STATUS_CONFIG).map(({ label, classes }) => ( + + + {label} + + + ))} +
+ +
+ {data.map(({ category, items }) => { + const isOpen = openCategories.has(category); + return ( +
+ + + {isOpen && ( +
    + {items.map(({ name, status, href }) => ( +
  • + {href ? ( + + {name} + + ) : ( + {name} + )} + +
  • + ))} +
+ )} +
+ ); + })} +
+
+ ); +} diff --git a/app/components/resources/ResourceTreeData.tsx b/app/components/resources/ResourceTreeData.tsx new file mode 100644 index 0000000..5ed2db5 --- /dev/null +++ b/app/components/resources/ResourceTreeData.tsx @@ -0,0 +1,87 @@ +import { ResourceTree } from "./ResourceTree"; +import type { ResourceCategory } from "./resource-tree-types"; + +const DOCS_BASE = "https://docs.medusajs.com"; +const MODULES_URL = `${DOCS_BASE}/resources/commerce-modules/index.html.md`; +const INTEGRATIONS_URL = `${DOCS_BASE}/resources/integrations/index.html.md`; + +function fixDocsUrl(href: string): string { + return href.replace(DOCS_BASE + "/", DOCS_BASE + "/resources/"); +} + +async function fetchModules(): Promise { + try { + const res = await fetch(MODULES_URL, { next: { revalidate: 86400 } }); + if (!res.ok) throw new Error(`Fetch error: ${res.status}`); + const text = await res.text(); + return { + category: "Commerce Modules", + items: parseMarkdownLinks(text).map((item) => ({ + ...item, + status: "built-in" as const, + })), + }; + } catch { + return { category: "Commerce Modules", items: [] }; + } +} + +async function fetchIntegrations(): Promise { + try { + const res = await fetch(INTEGRATIONS_URL, { next: { revalidate: 86400 } }); + if (!res.ok) throw new Error(`Fetch error: ${res.status}`); + const text = await res.text(); + return parseMarkdownByCategory(text); + } catch { + return []; + } +} + +function parseMarkdownLinks(text: string): { name: string; href: string }[] { + const items: { name: string; href: string }[] = []; + for (const line of text.split("\n")) { + const match = line.match(/^-\s+\[([^\]]+)\]\(([^)]+)\)/); + if (match) { + items.push({ name: match[1].trim(), href: fixDocsUrl(match[2].trim()) }); + } + } + return items; +} + +function parseMarkdownByCategory(text: string): ResourceCategory[] { + const categories: ResourceCategory[] = []; + let current: ResourceCategory | null = null; + + for (const line of text.split("\n")) { + const heading = line.match(/^##\s+(.+)/); + if (heading) { + current = { category: heading[1].trim(), items: [] }; + categories.push(current); + continue; + } + + if (!current) continue; + + const link = line.match(/^-\s+\[([^\]]+)\]\(([^)]+)\)/); + if (link) { + current.items.push({ + name: link[1].trim(), + status: "plugin", + href: fixDocsUrl(link[2].trim()), + }); + } + } + + return categories.filter((c) => c.items.length > 0); +} + +export default async function ResourceTreeData() { + const [modulesCategory, integrationCategories] = await Promise.all([ + fetchModules(), + fetchIntegrations(), + ]); + + const data = [modulesCategory, ...integrationCategories]; + + return ; +} diff --git a/app/components/resources/resource-tree-types.ts b/app/components/resources/resource-tree-types.ts new file mode 100644 index 0000000..03bc0f9 --- /dev/null +++ b/app/components/resources/resource-tree-types.ts @@ -0,0 +1,12 @@ +export type Status = 'built-in' | 'plugin' + +export interface ResourceItem { + name: string + status: Status + href?: string +} + +export interface ResourceCategory { + category: string + items: ResourceItem[] +} diff --git a/content/medusajs/_meta.js b/content/medusajs/_meta.js index 784c97a..bc65f93 100644 --- a/content/medusajs/_meta.js +++ b/content/medusajs/_meta.js @@ -1,4 +1,5 @@ export default { + "resources": "Resources", "plugins": "Plugins", "starters": "Starters" } diff --git a/content/medusajs/index.mdx b/content/medusajs/index.mdx index c0e0ac6..197d773 100644 --- a/content/medusajs/index.mdx +++ b/content/medusajs/index.mdx @@ -8,6 +8,12 @@ asIndexPage: true This section contains modules, plugins, and guides for extending Medusa.js. +## Resources + +Browse built-in Medusa commerce modules and official third-party integrations. + +- [Browse Resources](/medusajs/resources) + ## Plugins Plugins extend Medusa.js functionality with additional features and integrations. diff --git a/content/medusajs/resources/index.mdx b/content/medusajs/resources/index.mdx new file mode 100644 index 0000000..17f84e6 --- /dev/null +++ b/content/medusajs/resources/index.mdx @@ -0,0 +1,12 @@ +--- +title: Medusa Resources +sidebarTitle: Resources +asIndexPage: true +--- + +# Medusa Resources + +A directory of built-in Medusa commerce modules and official third-party integrations. +Use this as a reference when evaluating what's possible out-of-the-box versus via a plugin. + + diff --git a/mdx-components.js b/mdx-components.js index d851ce7..a9e2a69 100644 --- a/mdx-components.js +++ b/mdx-components.js @@ -1,12 +1,14 @@ -import { useMDXComponents as getDocsMDXComponents } from 'nextra-theme-docs' -import { StarterVersion } from './app/components/StarterVersion' +import { useMDXComponents as getDocsMDXComponents } from "nextra-theme-docs"; +import { StarterVersion } from "./app/components/StarterVersion"; +import ResourceTreeData from "./app/components/resources/ResourceTreeData"; -const docsComponents = getDocsMDXComponents() +const docsComponents = getDocsMDXComponents(); export function useMDXComponents(components) { return { ...docsComponents, StarterVersion, - ...components - } -} \ No newline at end of file + ResourceTreeData, + ...components, + }; +} diff --git a/next-env.d.ts b/next-env.d.ts index 9edff1c..c4b7818 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/types/routes.d.ts"; +import "./.next/dev/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/postcss.config.mjs b/postcss.config.mjs new file mode 100644 index 0000000..a7f73a2 --- /dev/null +++ b/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +} From b015530e05d0cb1160093b9037cb681520e6ab2d Mon Sep 17 00:00:00 2001 From: Krzysztof Polak Date: Fri, 3 Apr 2026 19:25:22 +0200 Subject: [PATCH 2/4] feat: implement wizard component for resource configuration - Add WizardShell component to manage the wizard steps and state - Create StepIndicator for visual step tracking - Define WizardState and WIZARD_STEPS types in a new wizard.ts file - Implement layout for the wizard pages in WizardLayout component - Create WizardPage to render the WizardShell - Add CSS for wizard layout to ensure full-width display and hide unnecessary elements - Generate resources data from GitHub API and save to resources-generated.json - Add manual resources data to resources-manual.json - Create solutions data structure in solutions.json for resource management --- .claudeignore | 7 + .gitignore | 10 +- app/[[...mdxPath]]/page.jsx | 2 +- app/components/resources/ResourceTree.tsx | 130 --- app/components/resources/ResourceTreeData.tsx | 87 -- .../resources/resource-tree-types.ts | 12 - app/components/wizard/StepUseCases.tsx | 64 ++ app/components/wizard/WizardShell.tsx | 105 +++ app/layout.jsx | 58 +- app/types/wizard.ts | 28 + app/wizard/layout.tsx | 6 + app/wizard/page.tsx | 9 + app/wizard/wizard.css | 11 + content/medusajs/_meta.js | 1 - content/medusajs/resources/index.mdx | 12 - data/resources-generated.json | 380 +++++++++ data/resources-manual.json | 20 + data/solutions.json | 563 +++++++++++++ mdx-components.js | 2 - package.json | 5 +- scripts/fetch-resources.ts | 133 +++ yarn.lock | 772 +++++++++++++++++- 22 files changed, 2122 insertions(+), 295 deletions(-) create mode 100644 .claudeignore delete mode 100644 app/components/resources/ResourceTree.tsx delete mode 100644 app/components/resources/ResourceTreeData.tsx delete mode 100644 app/components/resources/resource-tree-types.ts create mode 100644 app/components/wizard/StepUseCases.tsx create mode 100644 app/components/wizard/WizardShell.tsx create mode 100644 app/types/wizard.ts create mode 100644 app/wizard/layout.tsx create mode 100644 app/wizard/page.tsx create mode 100644 app/wizard/wizard.css delete mode 100644 content/medusajs/resources/index.mdx create mode 100644 data/resources-generated.json create mode 100644 data/resources-manual.json create mode 100644 data/solutions.json create mode 100644 scripts/fetch-resources.ts diff --git a/.claudeignore b/.claudeignore new file mode 100644 index 0000000..edd40e8 --- /dev/null +++ b/.claudeignore @@ -0,0 +1,7 @@ +# Environment variables +.env +.env.local +.env.*.local +.env.development.local +.env.test.local +.env.production.local diff --git a/.gitignore b/.gitignore index c4a70af..b869a13 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,12 @@ node_modules .nextra-cache .nextra-dist .nextra-static -_pagefind/ \ No newline at end of file +_pagefind/ + +# Environment variables +.env +.env.local +.env.*.local +.env.development.local +.env.test.local +.env.production.local \ No newline at end of file diff --git a/app/[[...mdxPath]]/page.jsx b/app/[[...mdxPath]]/page.jsx index 150b33b..264cabb 100644 --- a/app/[[...mdxPath]]/page.jsx +++ b/app/[[...mdxPath]]/page.jsx @@ -24,4 +24,4 @@ export default async function Page(props) { ) -} \ No newline at end of file +} diff --git a/app/components/resources/ResourceTree.tsx b/app/components/resources/ResourceTree.tsx deleted file mode 100644 index 043aab1..0000000 --- a/app/components/resources/ResourceTree.tsx +++ /dev/null @@ -1,130 +0,0 @@ -"use client"; - -import { useState } from "react"; -import type { ResourceCategory, Status } from "./resource-tree-types"; - -const STATUS_CONFIG: Record = { - "built-in": { - label: "Built-in", - classes: - "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200", - }, - plugin: { - label: "Plugin", - classes: "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200", - }, -}; - -function StatusBadge({ status }: { status: Status }) { - const config = STATUS_CONFIG[status]; - return ( - - {config.label} - - ); -} - -function ChevronIcon({ open }: { open: boolean }) { - return ( - - - - ); -} - -export function ResourceTree({ data }: { data: ResourceCategory[] }) { - const [openCategories, setOpenCategories] = useState>( - () => new Set() - ); - - function toggle(category: string) { - setOpenCategories((prev) => { - const next = new Set(prev); - if (next.has(category)) { - next.delete(category); - } else { - next.add(category); - } - return next; - }); - } - - return ( -
-
- {Object.values(STATUS_CONFIG).map(({ label, classes }) => ( - - - {label} - - - ))} -
- -
- {data.map(({ category, items }) => { - const isOpen = openCategories.has(category); - return ( -
- - - {isOpen && ( -
    - {items.map(({ name, status, href }) => ( -
  • - {href ? ( - - {name} - - ) : ( - {name} - )} - -
  • - ))} -
- )} -
- ); - })} -
-
- ); -} diff --git a/app/components/resources/ResourceTreeData.tsx b/app/components/resources/ResourceTreeData.tsx deleted file mode 100644 index 5ed2db5..0000000 --- a/app/components/resources/ResourceTreeData.tsx +++ /dev/null @@ -1,87 +0,0 @@ -import { ResourceTree } from "./ResourceTree"; -import type { ResourceCategory } from "./resource-tree-types"; - -const DOCS_BASE = "https://docs.medusajs.com"; -const MODULES_URL = `${DOCS_BASE}/resources/commerce-modules/index.html.md`; -const INTEGRATIONS_URL = `${DOCS_BASE}/resources/integrations/index.html.md`; - -function fixDocsUrl(href: string): string { - return href.replace(DOCS_BASE + "/", DOCS_BASE + "/resources/"); -} - -async function fetchModules(): Promise { - try { - const res = await fetch(MODULES_URL, { next: { revalidate: 86400 } }); - if (!res.ok) throw new Error(`Fetch error: ${res.status}`); - const text = await res.text(); - return { - category: "Commerce Modules", - items: parseMarkdownLinks(text).map((item) => ({ - ...item, - status: "built-in" as const, - })), - }; - } catch { - return { category: "Commerce Modules", items: [] }; - } -} - -async function fetchIntegrations(): Promise { - try { - const res = await fetch(INTEGRATIONS_URL, { next: { revalidate: 86400 } }); - if (!res.ok) throw new Error(`Fetch error: ${res.status}`); - const text = await res.text(); - return parseMarkdownByCategory(text); - } catch { - return []; - } -} - -function parseMarkdownLinks(text: string): { name: string; href: string }[] { - const items: { name: string; href: string }[] = []; - for (const line of text.split("\n")) { - const match = line.match(/^-\s+\[([^\]]+)\]\(([^)]+)\)/); - if (match) { - items.push({ name: match[1].trim(), href: fixDocsUrl(match[2].trim()) }); - } - } - return items; -} - -function parseMarkdownByCategory(text: string): ResourceCategory[] { - const categories: ResourceCategory[] = []; - let current: ResourceCategory | null = null; - - for (const line of text.split("\n")) { - const heading = line.match(/^##\s+(.+)/); - if (heading) { - current = { category: heading[1].trim(), items: [] }; - categories.push(current); - continue; - } - - if (!current) continue; - - const link = line.match(/^-\s+\[([^\]]+)\]\(([^)]+)\)/); - if (link) { - current.items.push({ - name: link[1].trim(), - status: "plugin", - href: fixDocsUrl(link[2].trim()), - }); - } - } - - return categories.filter((c) => c.items.length > 0); -} - -export default async function ResourceTreeData() { - const [modulesCategory, integrationCategories] = await Promise.all([ - fetchModules(), - fetchIntegrations(), - ]); - - const data = [modulesCategory, ...integrationCategories]; - - return ; -} diff --git a/app/components/resources/resource-tree-types.ts b/app/components/resources/resource-tree-types.ts deleted file mode 100644 index 03bc0f9..0000000 --- a/app/components/resources/resource-tree-types.ts +++ /dev/null @@ -1,12 +0,0 @@ -export type Status = 'built-in' | 'plugin' - -export interface ResourceItem { - name: string - status: Status - href?: string -} - -export interface ResourceCategory { - category: string - items: ResourceItem[] -} diff --git a/app/components/wizard/StepUseCases.tsx b/app/components/wizard/StepUseCases.tsx new file mode 100644 index 0000000..fd52ad9 --- /dev/null +++ b/app/components/wizard/StepUseCases.tsx @@ -0,0 +1,64 @@ +"use client"; + +import type { UseCase, WizardState } from "../../types/wizard"; + +const USE_CASES: { id: UseCase; label: string; description: string }[] = [ + { + id: "b2c", + label: "B2C", + description: "Sklep dla klientów indywidualnych", + }, + { + id: "b2b", + label: "B2B", + description: "Platforma dla klientów biznesowych", + }, +]; + +interface Props { + state: WizardState; + onChange: (state: Partial) => void; +} + +export function StepUseCases({ state, onChange }: Props) { + function toggle(id: UseCase) { + const current = state.useCases; + const next = current.includes(id) + ? current.filter((u) => u !== id) + : [...current, id]; + onChange({ useCases: next }); + } + + return ( +
+
+

Jaki sklep chcesz zbudować?

+

+ Możesz wybrać oba +

+
+ +
+ {USE_CASES.map(({ id, label, description }) => { + const selected = state.useCases.includes(id); + return ( + + ); + })} +
+
+ ); +} diff --git a/app/components/wizard/WizardShell.tsx b/app/components/wizard/WizardShell.tsx new file mode 100644 index 0000000..b998e64 --- /dev/null +++ b/app/components/wizard/WizardShell.tsx @@ -0,0 +1,105 @@ +"use client"; + +import { useState } from "react"; +import { WIZARD_STEPS, type WizardState } from "../../types/wizard"; +import { StepUseCases } from "./StepUseCases"; + +const INITIAL_STATE: WizardState = { + useCases: [], + selectedCategoryIds: [], +}; + +function StepIndicator({ currentIndex }: { currentIndex: number }) { + return ( +
+ {WIZARD_STEPS.map((step, i) => ( +
+
+ {i < currentIndex ? "✓" : i + 1} +
+ + {step.label} + + {i < WIZARD_STEPS.length - 1 && ( +
+ )} +
+ ))} +
+ ); +} + +function canProceed(step: number, state: WizardState): boolean { + if (step === 0) return state.useCases.length > 0; + if (step === 1) return state.selectedCategoryIds.length > 0; + return true; +} + +export function WizardShell() { + const [step, setStep] = useState(0); + const [state, setState] = useState(INITIAL_STATE); + + function update(partial: Partial) { + setState((prev) => ({ ...prev, ...partial })); + } + + function renderStep() { + switch (step) { + case 0: + return ; + default: + return ( +
+ Krok {step + 1} — wkrótce +
+ ); + } + } + + return ( +
+ {/* Step indicator */} +
+ +
+ + {/* Content */} +
+ {renderStep()} +
+ + {/* Fixed bottom bar */} +
+
+ + + {step + 1} / {WIZARD_STEPS.length} + + +
+
+
+ ); +} diff --git a/app/layout.jsx b/app/layout.jsx index f511460..96c66b5 100644 --- a/app/layout.jsx +++ b/app/layout.jsx @@ -1,74 +1,42 @@ import { Footer, Layout, Navbar } from 'nextra-theme-docs' -import { Banner, Head } from 'nextra/components' +import { Head } from 'nextra/components' import { getPageMap } from 'nextra/page-map' import 'nextra-theme-docs/style.css' import './globals.css' - + export const metadata = { title: 'Medusa Hub', description: 'Community plugins, starters, and guides extending Medusa.js.', } - -// const banner = Nextra 4.0 is released 🎉 + const navbar = ( - Medusa Hub - } - // ... Your additional navbar options - /> + Medusa Hub} /> ) -const currentYear = typeof window === 'undefined' ? new Date().getFullYear() : new Date().getFullYear() + +const currentYear = new Date().getFullYear() const footer = ( ) - + export default async function RootLayout({ children }) { const pageMap = await getPageMap() - + return ( - - - {/* Your additional tags should be passed as `children` of `` element */} - + + - + {children} diff --git a/app/types/wizard.ts b/app/types/wizard.ts new file mode 100644 index 0000000..678c5d7 --- /dev/null +++ b/app/types/wizard.ts @@ -0,0 +1,28 @@ +export type UseCase = "b2c" | "b2b"; + +export type SolutionStatus = "ready" | "configurable" | "plugin" | "buildable" | "missing"; + +export interface Solution { + id: string; + name: string; + useCases: UseCase[]; + status?: SolutionStatus; + description?: string; + resourceIds?: string[]; + notes?: string; + children?: Solution[]; +} + +export interface WizardState { + useCases: UseCase[]; + selectedCategoryIds: string[]; +} + +export const WIZARD_STEPS = [ + { id: "use-cases", label: "Use Case" }, + { id: "categories", label: "Categories" }, + { id: "features", label: "Features" }, + { id: "summary", label: "Summary" }, +] as const; + +export type WizardStepId = (typeof WIZARD_STEPS)[number]["id"]; diff --git a/app/wizard/layout.tsx b/app/wizard/layout.tsx new file mode 100644 index 0000000..414a760 --- /dev/null +++ b/app/wizard/layout.tsx @@ -0,0 +1,6 @@ +import type { ReactNode } from "react"; +import "./wizard.css"; + +export default function WizardLayout({ children }: { children: ReactNode }) { + return
{children}
; +} diff --git a/app/wizard/page.tsx b/app/wizard/page.tsx new file mode 100644 index 0000000..aadaf73 --- /dev/null +++ b/app/wizard/page.tsx @@ -0,0 +1,9 @@ +import { WizardShell } from "../components/wizard/WizardShell"; + +export const metadata = { + title: "Configurator — Medusa Hub", +}; + +export default function WizardPage() { + return ; +} diff --git a/app/wizard/wizard.css b/app/wizard/wizard.css new file mode 100644 index 0000000..f088028 --- /dev/null +++ b/app/wizard/wizard.css @@ -0,0 +1,11 @@ +/* Hide Nextra sidebar and TOC on wizard pages */ +.wizard-layout ~ aside, +.nextra-sidebar-container, +.nextra-toc { + display: none !important; +} + +/* Make content full width */ +.wizard-layout { + width: 100%; +} diff --git a/content/medusajs/_meta.js b/content/medusajs/_meta.js index bc65f93..784c97a 100644 --- a/content/medusajs/_meta.js +++ b/content/medusajs/_meta.js @@ -1,5 +1,4 @@ export default { - "resources": "Resources", "plugins": "Plugins", "starters": "Starters" } diff --git a/content/medusajs/resources/index.mdx b/content/medusajs/resources/index.mdx deleted file mode 100644 index 17f84e6..0000000 --- a/content/medusajs/resources/index.mdx +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: Medusa Resources -sidebarTitle: Resources -asIndexPage: true ---- - -# Medusa Resources - -A directory of built-in Medusa commerce modules and official third-party integrations. -Use this as a reference when evaluating what's possible out-of-the-box versus via a plugin. - - diff --git a/data/resources-generated.json b/data/resources-generated.json new file mode 100644 index 0000000..f894ef5 --- /dev/null +++ b/data/resources-generated.json @@ -0,0 +1,380 @@ +[ + { + "id": "api-key", + "name": "API Key Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/api-key", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "auth", + "name": "Auth Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/auth", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "cart", + "name": "Cart Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/cart", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "currency", + "name": "Currency Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/currency", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "customer", + "name": "Customer Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/customer", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "fulfillment", + "name": "Fulfillment Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/fulfillment", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "inventory", + "name": "Inventory Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/inventory", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "order", + "name": "Order Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/order", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "payment", + "name": "Payment Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/payment", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "pricing", + "name": "Pricing Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/pricing", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "product", + "name": "Product Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/product", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "promotion", + "name": "Promotion Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/promotion", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "region", + "name": "Region Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/region", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "sales-channel", + "name": "Sales Channel Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/sales-channel", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "stock-location", + "name": "Stock Location Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/stock-location", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "store", + "name": "Store Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/store", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "tax", + "name": "Tax Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/tax", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "translation", + "name": "Translation Module", + "href": "https://docs.medusajs.com/resources/commerce-modules/translation", + "type": "built-in", + "author": "medusa", + "sourceCategory": "Commerce Modules", + "useCases": [] + }, + { + "id": "posthog", + "name": "PostHog", + "href": "https://docs.medusajs.com/resources/infrastructure-modules/analytics/posthog", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Analytics" + }, + { + "id": "segment", + "name": "Segment", + "href": "https://docs.medusajs.com/resources/integrations/guides/segment", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Analytics" + }, + { + "id": "google", + "name": "Google", + "href": "https://docs.medusajs.com/resources/commerce-modules/auth/auth-providers/google", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Auth" + }, + { + "id": "github", + "name": "GitHub", + "href": "https://docs.medusajs.com/resources/commerce-modules/auth/auth-providers/github", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Auth" + }, + { + "id": "okta", + "name": "Okta", + "href": "https://docs.medusajs.com/resources/integrations/guides/okta", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Auth" + }, + { + "id": "contentful", + "name": "Contentful (Localization)", + "href": "https://docs.medusajs.com/resources/integrations/guides/contentful", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "CMS" + }, + { + "id": "payload", + "name": "Payload CMS", + "href": "https://docs.medusajs.com/resources/integrations/guides/payload", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "CMS" + }, + { + "id": "sanity", + "name": "Sanity", + "href": "https://docs.medusajs.com/resources/integrations/guides/sanity", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "CMS" + }, + { + "id": "strapi", + "name": "Strapi", + "href": "https://docs.medusajs.com/resources/integrations/guides/strapi", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "CMS" + }, + { + "id": "odoo", + "name": "Odoo", + "href": "https://docs.medusajs.com/resources/recipes/erp/odoo", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "ERP" + }, + { + "id": "s3", + "name": "AWS S3 (and Compatible APIs)", + "href": "https://docs.medusajs.com/resources/infrastructure-modules/file/s3", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "File" + }, + { + "id": "shipstation", + "name": "ShipStation", + "href": "https://docs.medusajs.com/resources/integrations/guides/shipstation", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Fulfillment" + }, + { + "id": "sentry", + "name": "Sentry", + "href": "https://docs.medusajs.com/resources/integrations/guides/sentry", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Instrumentation" + }, + { + "id": "magento", + "name": "Magento", + "href": "https://docs.medusajs.com/resources/integrations/guides/magento", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Migration" + }, + { + "id": "sendgrid", + "name": "SendGrid", + "href": "https://docs.medusajs.com/resources/infrastructure-modules/notification/sendgrid", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Notification" + }, + { + "id": "mailchimp", + "name": "Mailchimp", + "href": "https://docs.medusajs.com/resources/integrations/guides/mailchimp", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Notification" + }, + { + "id": "resend", + "name": "Resend", + "href": "https://docs.medusajs.com/resources/integrations/guides/resend", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Notification" + }, + { + "id": "slack", + "name": "Slack", + "href": "https://docs.medusajs.com/resources/integrations/guides/slack", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Notification" + }, + { + "id": "phone-auth#step-3-integrate-twilio-sms", + "name": "Twilio SMS", + "href": "https://docs.medusajs.com/resources/how-to-tutorials/tutorials/phone-auth#step-3-integrate-twilio-sms", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Notification" + }, + { + "id": "stripe", + "name": "Stripe", + "href": "https://docs.medusajs.com/resources/commerce-modules/payment/payment-provider/stripe", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Payment" + }, + { + "id": "paypal", + "name": "PayPal", + "href": "https://docs.medusajs.com/resources/integrations/guides/paypal", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Payment" + }, + { + "id": "algolia", + "name": "Algolia", + "href": "https://docs.medusajs.com/resources/integrations/guides/algolia", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Search" + }, + { + "id": "meilisearch", + "name": "Meilisearch", + "href": "https://docs.medusajs.com/resources/integrations/guides/meilisearch", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Search" + }, + { + "id": "avalara", + "name": "Avalara", + "href": "https://docs.medusajs.com/resources/integrations/guides/avalara", + "type": "guide", + "author": "medusa", + "useCases": [], + "sourceCategory": "Tax" + } +] \ No newline at end of file diff --git a/data/resources-manual.json b/data/resources-manual.json new file mode 100644 index 0000000..6b4af79 --- /dev/null +++ b/data/resources-manual.json @@ -0,0 +1,20 @@ +[ + { + "id": "custom-erp", + "name": "ERP Integration", + "type": "custom", + "author": null, + "sourceCategory": "ERP", + "useCases": ["b2b"], + "notes": "Brak oficjalnego wsparcia — wymaga własnej implementacji" + }, + { + "id": "custom-b2b-quotes", + "name": "Quote Management", + "type": "missing", + "author": null, + "sourceCategory": "Sales", + "useCases": ["b2b"], + "notes": "Brak natywnego wsparcia dla ofertowania B2B" + } +] diff --git a/data/solutions.json b/data/solutions.json new file mode 100644 index 0000000..64c44ed --- /dev/null +++ b/data/solutions.json @@ -0,0 +1,563 @@ +[ + { + "id": "catalog", + "name": "Catalog", + "useCases": ["b2c", "b2b"], + "description": "Zarządzanie produktami i asortymentem", + "children": [ + { + "id": "catalog-products", + "name": "Products", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["product"], + "children": [ + { + "id": "catalog-products-variants", + "name": "Variants", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["product"] + }, + { + "id": "catalog-products-custom-attributes", + "name": "Custom Attributes", + "useCases": ["b2c", "b2b"], + "status": "buildable", + "resourceIds": ["product"], + "notes": "Wymaga rozszerzenia modelu danych" + }, + { + "id": "catalog-products-digital", + "name": "Digital Products", + "useCases": ["b2c"], + "status": "buildable", + "resourceIds": [], + "notes": "Brak natywnego wsparcia — można zbudować na bazie Product Module" + } + ] + }, + { + "id": "catalog-categories", + "name": "Categories", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["product"] + }, + { + "id": "catalog-collections", + "name": "Collections", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["product"] + }, + { + "id": "catalog-inventory", + "name": "Inventory", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["inventory", "stock-location"], + "children": [ + { + "id": "catalog-inventory-multi-warehouse", + "name": "Multi-warehouse", + "useCases": ["b2b"], + "status": "ready", + "resourceIds": ["inventory", "stock-location"] + }, + { + "id": "catalog-inventory-reservations", + "name": "Reservations", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["inventory"] + } + ] + } + ] + }, + { + "id": "pricing", + "name": "Pricing", + "useCases": ["b2c", "b2b"], + "description": "Cenniki, rabaty, waluty", + "children": [ + { + "id": "pricing-price-lists", + "name": "Price Lists", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["pricing"] + }, + { + "id": "pricing-currencies", + "name": "Multi-currency", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["currency", "region"] + }, + { + "id": "pricing-taxes", + "name": "Taxes", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["tax"], + "children": [ + { + "id": "pricing-taxes-avalara", + "name": "Avalara Integration", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["avalara"] + } + ] + }, + { + "id": "pricing-promotions", + "name": "Promotions & Discounts", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["promotion"] + }, + { + "id": "pricing-b2b-per-company", + "name": "Per-company Pricing", + "useCases": ["b2b"], + "status": "buildable", + "resourceIds": ["pricing"], + "notes": "Wymaga niestandardowej logiki przypisania cenników do firm" + } + ] + }, + { + "id": "cart-checkout", + "name": "Cart & Checkout", + "useCases": ["b2c", "b2b"], + "description": "Koszyk i proces zakupowy", + "children": [ + { + "id": "cart-checkout-cart", + "name": "Cart", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["cart"] + }, + { + "id": "cart-checkout-guest", + "name": "Guest Checkout", + "useCases": ["b2c"], + "status": "ready", + "resourceIds": ["cart"] + }, + { + "id": "cart-checkout-multi-step", + "name": "Multi-step Checkout", + "useCases": ["b2c", "b2b"], + "status": "buildable", + "resourceIds": ["cart"], + "notes": "Logika kroków zdefiniowana po stronie frontendu" + }, + { + "id": "cart-checkout-abandoned", + "name": "Abandoned Cart Recovery", + "useCases": ["b2c"], + "status": "buildable", + "resourceIds": ["cart"], + "notes": "Wymaga własnego mechanizmu schedulera i notyfikacji" + } + ] + }, + { + "id": "payments", + "name": "Payments", + "useCases": ["b2c", "b2b"], + "description": "Integracje płatności", + "children": [ + { + "id": "payments-stripe", + "name": "Stripe", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["stripe"] + }, + { + "id": "payments-paypal", + "name": "PayPal", + "useCases": ["b2c"], + "status": "plugin", + "resourceIds": ["paypal"] + }, + { + "id": "payments-subscriptions", + "name": "Subscriptions", + "useCases": ["b2c", "b2b"], + "status": "buildable", + "resourceIds": ["payment"], + "notes": "Brak natywnego modułu subskrypcji — wymaga własnej implementacji" + }, + { + "id": "payments-invoice", + "name": "Invoice / Pay by Terms", + "useCases": ["b2b"], + "status": "buildable", + "resourceIds": ["payment"], + "notes": "Typowy scenariusz B2B — płatność przelewem po terminie" + } + ] + }, + { + "id": "customers", + "name": "Customers", + "useCases": ["b2c", "b2b"], + "description": "Konta, autoryzacja, segmentacja", + "children": [ + { + "id": "customers-accounts", + "name": "Customer Accounts", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["customer"] + }, + { + "id": "customers-auth", + "name": "Authentication", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["auth"], + "children": [ + { + "id": "customers-auth-google", + "name": "Google OAuth", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["google"] + }, + { + "id": "customers-auth-github", + "name": "GitHub OAuth", + "useCases": ["b2b"], + "status": "plugin", + "resourceIds": ["github"] + }, + { + "id": "customers-auth-okta", + "name": "Okta / SSO", + "useCases": ["b2b"], + "status": "plugin", + "resourceIds": ["okta"] + } + ] + }, + { + "id": "customers-groups", + "name": "Customer Groups", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["customer"] + }, + { + "id": "customers-company-accounts", + "name": "Company Accounts", + "useCases": ["b2b"], + "status": "missing", + "resourceIds": [], + "notes": "Brak natywnego wsparcia dla struktur firmowych (firma → pracownicy → role)" + }, + { + "id": "customers-approval-flows", + "name": "Approval Flows", + "useCases": ["b2b"], + "status": "missing", + "resourceIds": [], + "notes": "Zatwierdzanie zamówień przez managera — brak wsparcia" + } + ] + }, + { + "id": "orders", + "name": "Orders", + "useCases": ["b2c", "b2b"], + "description": "Zarządzanie zamówieniami", + "children": [ + { + "id": "orders-management", + "name": "Order Management", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["order"] + }, + { + "id": "orders-returns", + "name": "Returns & Refunds", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["order"] + }, + { + "id": "orders-exchanges", + "name": "Exchanges", + "useCases": ["b2c"], + "status": "ready", + "resourceIds": ["order"] + }, + { + "id": "orders-quotes", + "name": "Quote Management", + "useCases": ["b2b"], + "status": "missing", + "resourceIds": [], + "notes": "Ofertowanie B2B — brak natywnego wsparcia" + }, + { + "id": "orders-bulk", + "name": "Bulk Orders", + "useCases": ["b2b"], + "status": "buildable", + "resourceIds": ["order"], + "notes": "Możliwe przez API, wymaga własnego UI i logiki" + } + ] + }, + { + "id": "fulfillment", + "name": "Fulfillment", + "useCases": ["b2c", "b2b"], + "description": "Wysyłka i realizacja zamówień", + "children": [ + { + "id": "fulfillment-shipping", + "name": "Shipping", + "useCases": ["b2c", "b2b"], + "status": "ready", + "resourceIds": ["fulfillment"] + }, + { + "id": "fulfillment-shipstation", + "name": "ShipStation", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["shipstation"] + }, + { + "id": "fulfillment-dropshipping", + "name": "Dropshipping", + "useCases": ["b2c"], + "status": "buildable", + "resourceIds": ["fulfillment"], + "notes": "Wymaga własnej integracji z dostawcą dropshipping" + } + ] + }, + { + "id": "search", + "name": "Search & Discovery", + "useCases": ["b2c", "b2b"], + "description": "Wyszukiwanie i rekomendacje", + "children": [ + { + "id": "search-algolia", + "name": "Algolia", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["algolia"] + }, + { + "id": "search-meilisearch", + "name": "Meilisearch", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["meilisearch"] + }, + { + "id": "search-filters", + "name": "Faceted Filters", + "useCases": ["b2c", "b2b"], + "status": "buildable", + "resourceIds": [], + "notes": "Wymaga integracji z silnikiem wyszukiwania" + } + ] + }, + { + "id": "content", + "name": "Content", + "useCases": ["b2c", "b2b"], + "description": "CMS i zarządzanie treścią", + "children": [ + { + "id": "content-contentful", + "name": "Contentful", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["contentful"] + }, + { + "id": "content-sanity", + "name": "Sanity", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["sanity"] + }, + { + "id": "content-payload", + "name": "Payload CMS", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["payload"] + }, + { + "id": "content-media", + "name": "Media / File Storage", + "useCases": ["b2c", "b2b"], + "status": "configurable", + "resourceIds": ["s3"], + "children": [ + { + "id": "content-media-s3", + "name": "AWS S3", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["s3"] + } + ] + } + ] + }, + { + "id": "notifications", + "name": "Notifications", + "useCases": ["b2c", "b2b"], + "description": "Email, SMS, powiadomienia", + "children": [ + { + "id": "notifications-sendgrid", + "name": "SendGrid", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["sendgrid"] + }, + { + "id": "notifications-resend", + "name": "Resend", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["resend"] + }, + { + "id": "notifications-sms", + "name": "SMS (Twilio)", + "useCases": ["b2c"], + "status": "plugin", + "resourceIds": ["twilio-sms"] + }, + { + "id": "notifications-slack", + "name": "Slack", + "useCases": ["b2b"], + "status": "plugin", + "resourceIds": ["slack"] + } + ] + }, + { + "id": "analytics", + "name": "Analytics", + "useCases": ["b2c", "b2b"], + "description": "Śledzenie zdarzeń i zachowań", + "children": [ + { + "id": "analytics-posthog", + "name": "PostHog", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["posthog"] + }, + { + "id": "analytics-segment", + "name": "Segment", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["segment"] + } + ] + }, + { + "id": "infrastructure", + "name": "Infrastructure", + "useCases": ["b2c", "b2b"], + "description": "Monitoring, deployment, wydajność", + "children": [ + { + "id": "infrastructure-sentry", + "name": "Sentry", + "useCases": ["b2c", "b2b"], + "status": "plugin", + "resourceIds": ["sentry"] + }, + { + "id": "infrastructure-deployment", + "name": "Deployment", + "useCases": ["b2c", "b2b"], + "status": "configurable", + "resourceIds": [], + "notes": "Medusa wspiera Railway, Render, AWS, GCP, DigitalOcean" + } + ] + }, + { + "id": "b2b-specific", + "name": "B2B Specific", + "useCases": ["b2b"], + "description": "Funkcje dedykowane dla B2B", + "children": [ + { + "id": "b2b-company-accounts", + "name": "Company Accounts", + "useCases": ["b2b"], + "status": "missing", + "resourceIds": [], + "notes": "Struktura firma → oddziały → pracownicy z rolami" + }, + { + "id": "b2b-quotes", + "name": "Quote Management", + "useCases": ["b2b"], + "status": "missing", + "resourceIds": [], + "notes": "Ofertowanie, negocjacje cen" + }, + { + "id": "b2b-approval-flows", + "name": "Approval Flows", + "useCases": ["b2b"], + "status": "missing", + "resourceIds": [], + "notes": "Zatwierdzanie zamówień przez przełożonego" + }, + { + "id": "b2b-credit-limit", + "name": "Credit Limit", + "useCases": ["b2b"], + "status": "buildable", + "resourceIds": ["customer"], + "notes": "Limit kredytowy na firmę — wymaga własnej logiki" + }, + { + "id": "b2b-contract-pricing", + "name": "Contract Pricing", + "useCases": ["b2b"], + "status": "buildable", + "resourceIds": ["pricing"], + "notes": "Indywidualne cenniki negocjowane per firma" + }, + { + "id": "b2b-erp", + "name": "ERP Integration", + "useCases": ["b2b"], + "status": "buildable", + "resourceIds": ["odoo"], + "notes": "Medusa ma guide dla Odoo, pozostałe ERP wymagają własnej implementacji" + } + ] + } +] diff --git a/mdx-components.js b/mdx-components.js index a9e2a69..200e11c 100644 --- a/mdx-components.js +++ b/mdx-components.js @@ -1,6 +1,5 @@ import { useMDXComponents as getDocsMDXComponents } from "nextra-theme-docs"; import { StarterVersion } from "./app/components/StarterVersion"; -import ResourceTreeData from "./app/components/resources/ResourceTreeData"; const docsComponents = getDocsMDXComponents(); @@ -8,7 +7,6 @@ export function useMDXComponents(components) { return { ...docsComponents, StarterVersion, - ResourceTreeData, ...components, }; } diff --git a/package.json b/package.json index 1b4e72a..9e9d007 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "dev": "next --turbopack", "build": "next build", "start": "next start", - "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind" + "postbuild": "pagefind --site .next/server/app --output-path public/_pagefind", + "fetch:resources": "tsx scripts/fetch-resources.ts" }, "dependencies": { "@tailwindcss/postcss": "^4.1.17", @@ -24,7 +25,9 @@ "devDependencies": { "@types/node": "24.10.1", "@types/react": "19.2.4", + "dotenv": "^17.4.0", "pagefind": "^1.4.0", + "tsx": "^4.19.3", "typescript": "^5.9.3" } } diff --git a/scripts/fetch-resources.ts b/scripts/fetch-resources.ts new file mode 100644 index 0000000..95cc3c4 --- /dev/null +++ b/scripts/fetch-resources.ts @@ -0,0 +1,133 @@ +#!/usr/bin/env tsx + +import { writeFileSync, mkdirSync } from "fs"; +import { join } from "path"; +import { config } from "dotenv"; + +config({ path: [".env.local", ".env"] }); + +const GITHUB_RAW = + "https://api.github.com/repos/medusajs/medusa/contents/www/apps/resources/app"; +const DOCS_BASE = "https://docs.medusajs.com/resources"; + +type Author = "medusa" | "community"; +type Status = "built-in" | "module" | "plugin" | "guide"; + +interface GeneratedResource { + id: string; + name: string; + href: string; + type: Status; + author: Author; + sourceCategory: string; + useCases: []; +} + +function githubHeaders(): Record { + const token = process.env.GITHUB_TOKEN; + return { + Accept: "application/vnd.github+json", + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }; +} + +async function fetchMdx(path: string): Promise { + const res = await fetch(`${GITHUB_RAW}/${path}`, { + headers: githubHeaders(), + }); + if (!res.ok) throw new Error(`GitHub API error: ${res.status} ${path}`); + const data = (await res.json()) as { content: string }; + return Buffer.from(data.content, "base64").toString("utf-8"); +} + +function slugFromHref(href: string): string { + return href.split("/").filter(Boolean).pop() ?? href; +} + +function parseCardListItems(mdx: string): { title: string; href: string }[] { + const items: { title: string; href: string }[] = []; + const itemRegex = + /\{\s*\n?\s*href:\s*"([^"]+)"[^}]*title:\s*"([^"]+)"|title:\s*"([^"]+)"[^}]*href:\s*"([^"]+)"/g; + let match: RegExpExecArray | null; + while ((match = itemRegex.exec(mdx)) !== null) { + const href = match[1] ?? match[4]; + const title = match[2] ?? match[3]; + if (href && title) { + items.push({ href, title }); + } + } + return items; +} + +function parseByCategory( + mdx: string, + type: Status, + author: Author +): { sourceCategory: string; items: Omit[] }[] { + const sections = mdx.split(/\n##\s+/); + const result: { sourceCategory: string; items: Omit[] }[] = []; + + for (const section of sections.slice(1)) { + const sourceCategory = section.split("\n")[0].trim(); + const items = parseCardListItems(section).map(({ title, href }) => ({ + id: slugFromHref(href), + name: title, + href: `${DOCS_BASE}${href}`, + type, + author, + useCases: [] as [], + })); + if (items.length > 0) { + result.push({ sourceCategory, items }); + } + } + + return result; +} + +async function fetchModules(): Promise { + console.log("Fetching commerce modules..."); + const mdx = await fetchMdx("commerce-modules/page.mdx"); + const items = parseCardListItems(mdx).map(({ title, href }) => ({ + id: slugFromHref(href), + name: title, + href: `${DOCS_BASE}${href}`, + type: "built-in" as const, + author: "medusa" as const, + sourceCategory: "Commerce Modules", + useCases: [] as [], + })); + console.log(` Found ${items.length} modules`); + return items; +} + +async function fetchIntegrations(): Promise { + console.log("Fetching integrations..."); + const mdx = await fetchMdx("integrations/page.mdx"); + const sections = parseByCategory(mdx, "guide", "medusa"); + const items: GeneratedResource[] = sections.flatMap(({ sourceCategory, items }) => + items.map((item) => ({ ...item, sourceCategory })) + ); + const total = items.length; + console.log(` Found ${sections.length} categories, ${total} integrations`); + return items; +} + +async function main() { + const [modules, integrations] = await Promise.all([ + fetchModules(), + fetchIntegrations(), + ]); + + const data: GeneratedResource[] = [...modules, ...integrations]; + + const outputPath = join(process.cwd(), "data", "resources-generated.json"); + mkdirSync(join(process.cwd(), "data"), { recursive: true }); + writeFileSync(outputPath, JSON.stringify(data, null, 2)); + console.log(`\nSaved ${data.length} resources to ${outputPath}`); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/yarn.lock b/yarn.lock index bd244ef..016df0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -106,6 +106,188 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/aix-ppc64@npm:0.27.7" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/android-arm64@npm:0.27.7" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/android-arm@npm:0.27.7" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/android-x64@npm:0.27.7" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/darwin-arm64@npm:0.27.7" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/darwin-x64@npm:0.27.7" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/freebsd-arm64@npm:0.27.7" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/freebsd-x64@npm:0.27.7" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-arm64@npm:0.27.7" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-arm@npm:0.27.7" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-ia32@npm:0.27.7" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-loong64@npm:0.27.7" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-mips64el@npm:0.27.7" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-ppc64@npm:0.27.7" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-riscv64@npm:0.27.7" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-s390x@npm:0.27.7" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/linux-x64@npm:0.27.7" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/netbsd-arm64@npm:0.27.7" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/netbsd-x64@npm:0.27.7" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/openbsd-arm64@npm:0.27.7" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/openbsd-x64@npm:0.27.7" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/openharmony-arm64@npm:0.27.7" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/sunos-x64@npm:0.27.7" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/win32-arm64@npm:0.27.7" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/win32-ia32@npm:0.27.7" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.27.7": + version: 0.27.7 + resolution: "@esbuild/win32-x64@npm:0.27.7" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@floating-ui/core@npm:^1.7.3": version: 1.7.3 resolution: "@floating-ui/core@npm:1.7.3" @@ -167,6 +349,13 @@ __metadata: languageName: node linkType: hard +"@gar/promise-retry@npm:^1.0.0": + version: 1.0.3 + resolution: "@gar/promise-retry@npm:1.0.3" + checksum: 0d13ea3bb1025755e055648f6e290d2a7e0c87affaf552218f09f66b3fcd9ea9d5c9cc5fe2aa6e285e1530437768e40f9448fe9a86f4f3417b216dcf488d3d1a + languageName: node + linkType: hard + "@headlessui/react@npm:^2.1.2": version: 2.2.9 resolution: "@headlessui/react@npm:2.2.9" @@ -449,6 +638,15 @@ __metadata: languageName: node linkType: hard +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: ^7.0.4 + checksum: 5d36d289960e886484362d9eb6a51d1ea28baed5f5d0140bbe62b99bac52eaf06cc01c2bc0d3575977962f84f6b2c4387b043ee632216643d4787b0999465bf2 + languageName: node + linkType: hard + "@jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.13 resolution: "@jridgewell/gen-mapping@npm:0.3.13" @@ -533,6 +731,7 @@ __metadata: "@tailwindcss/postcss": ^4.1.17 "@types/node": 24.10.1 "@types/react": 19.2.4 + dotenv: ^17.4.0 next: ^16.1.1 nextra: ^4.6.0 nextra-theme-docs: ^4.6.0 @@ -541,6 +740,7 @@ __metadata: react: ^19.2.1 react-dom: ^19.2.1 tailwindcss: ^4.1.17 + tsx: ^4.19.3 typescript: ^5.9.3 languageName: unknown linkType: soft @@ -814,6 +1014,35 @@ __metadata: languageName: node linkType: hard +"@npmcli/agent@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/agent@npm:4.0.0" + dependencies: + agent-base: ^7.1.0 + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.1 + lru-cache: ^11.2.1 + socks-proxy-agent: ^8.0.3 + checksum: 89ae20b44859ff8d4de56ade319d8ceaa267a0742d6f7345fe98aa5cd8614ced7db85ea4dc5bfbd6614dbb200a10b134e087143582534c939e8a02219e8665c8 + languageName: node + linkType: hard + +"@npmcli/fs@npm:^5.0.0": + version: 5.0.0 + resolution: "@npmcli/fs@npm:5.0.0" + dependencies: + semver: ^7.3.5 + checksum: 897dac32eb37e011800112d406b9ea2ebd96f1dab01bb8fbeb59191b86f6825dffed6a89f3b6c824753d10f8735b76d630927bd7610e9e123b129ef2e5f02cb5 + languageName: node + linkType: hard + +"@npmcli/redact@npm:^4.0.0": + version: 4.0.0 + resolution: "@npmcli/redact@npm:4.0.0" + checksum: 4e029c44a8593304bb1aa5a8f1559cb8f37b4dc3880c589ce546da0b8cfa741d16a054db38ee309e81c2120c148ba33edbb3252f97a78b3234ba9ab3fa3e176c + languageName: node + linkType: hard + "@pagefind/darwin-arm64@npm:1.4.0": version: 1.4.0 resolution: "@pagefind/darwin-arm64@npm:1.4.0" @@ -1692,6 +1921,13 @@ __metadata: languageName: node linkType: hard +"abbrev@npm:^4.0.0": + version: 4.0.0 + resolution: "abbrev@npm:4.0.0" + checksum: d0344b63d28e763f259b4898c41bdc92c08e9d06d0da5617d0bbe4d78244e46daea88c510a2f9472af59b031d9060ec1a999653144e793fd029a59dae2f56dc8 + languageName: node + linkType: hard + "acorn-jsx@npm:^5.0.0": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" @@ -1710,6 +1946,13 @@ __metadata: languageName: node linkType: hard +"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2": + version: 7.1.4 + resolution: "agent-base@npm:7.1.4" + checksum: 86a7f542af277cfbd77dd61e7df8422f90bac512953709003a1c530171a9d019d072e2400eab2b59f84b49ab9dd237be44315ca663ac73e82b3922d10ea5eafa + languageName: node + linkType: hard + "arg@npm:^5.0.0": version: 5.0.2 resolution: "arg@npm:5.0.2" @@ -1740,6 +1983,13 @@ __metadata: languageName: node linkType: hard +"balanced-match@npm:^4.0.2": + version: 4.0.4 + resolution: "balanced-match@npm:4.0.4" + checksum: fb07bb66a0959c2843fc055838047e2a95ccebb837c519614afb067ebfdf2fa967ca8d712c35ced07f2cd26fc6f07964230b094891315ad74f11eba3d53178a0 + languageName: node + linkType: hard + "baseline-browser-mapping@npm:^2.8.3": version: 2.10.0 resolution: "baseline-browser-mapping@npm:2.10.0" @@ -1760,6 +2010,15 @@ __metadata: languageName: node linkType: hard +"brace-expansion@npm:^5.0.5": + version: 5.0.5 + resolution: "brace-expansion@npm:5.0.5" + dependencies: + balanced-match: ^4.0.2 + checksum: 4481b7ffa467b34c14e258167dbd8d9485a2d31d03060e8e8b38142dcde32cdc89c8f55b04d3ae7aae9304fa7eac1dfafd602787cf09c019cc45de3bb6950ffc + languageName: node + linkType: hard + "braces@npm:^3.0.3": version: 3.0.3 resolution: "braces@npm:3.0.3" @@ -1769,6 +2028,24 @@ __metadata: languageName: node linkType: hard +"cacache@npm:^20.0.1": + version: 20.0.4 + resolution: "cacache@npm:20.0.4" + dependencies: + "@npmcli/fs": ^5.0.0 + fs-minipass: ^3.0.0 + glob: ^13.0.0 + lru-cache: ^11.1.0 + minipass: ^7.0.3 + minipass-collect: ^2.0.1 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + p-map: ^7.0.2 + ssri: ^13.0.0 + checksum: b368523e60f3105167cbeec633c19ee773588439b32754f63aa8767fc6ea293ad2d92a765882f0f088037411ef2cffecff7c33496bfc13b2ec3a4f0f6e45bfe2 + languageName: node + linkType: hard + "caniuse-lite@npm:^1.0.30001579": version: 1.0.30001754 resolution: "caniuse-lite@npm:1.0.30001754" @@ -1843,6 +2120,13 @@ __metadata: languageName: node linkType: hard +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: fd73a4bab48b79e66903fe1cafbdc208956f41ea4f856df883d0c7277b7ab29fd33ee65f93b2ec9192fc0169238f2f8307b7735d27c155821d886b84aa97aa8d + languageName: node + linkType: hard + "client-only@npm:0.0.1": version: 0.0.1 resolution: "client-only@npm:0.0.1" @@ -2366,7 +2650,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:^4.0.0, debug@npm:^4.1.1, debug@npm:^4.4.1": +"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.1, debug@npm:^4.3.4, debug@npm:^4.4.1": version: 4.4.3 resolution: "debug@npm:4.4.3" dependencies: @@ -2431,6 +2715,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^17.4.0": + version: 17.4.0 + resolution: "dotenv@npm:17.4.0" + checksum: 0404b1f9526aea6f442d68608158febd17d160e96e3accf240ff4305bc36ddaeab7675994673f08735c9a44898c97807d085e7e65cff3d0b6795f01d58ca08ca + languageName: node + linkType: hard + "enhanced-resolve@npm:^5.18.3": version: 5.18.3 resolution: "enhanced-resolve@npm:5.18.3" @@ -2448,6 +2739,13 @@ __metadata: languageName: node linkType: hard +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + "esast-util-from-estree@npm:^2.0.0": version: 2.0.0 resolution: "esast-util-from-estree@npm:2.0.0" @@ -2472,6 +2770,95 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:~0.27.0": + version: 0.27.7 + resolution: "esbuild@npm:0.27.7" + dependencies: + "@esbuild/aix-ppc64": 0.27.7 + "@esbuild/android-arm": 0.27.7 + "@esbuild/android-arm64": 0.27.7 + "@esbuild/android-x64": 0.27.7 + "@esbuild/darwin-arm64": 0.27.7 + "@esbuild/darwin-x64": 0.27.7 + "@esbuild/freebsd-arm64": 0.27.7 + "@esbuild/freebsd-x64": 0.27.7 + "@esbuild/linux-arm": 0.27.7 + "@esbuild/linux-arm64": 0.27.7 + "@esbuild/linux-ia32": 0.27.7 + "@esbuild/linux-loong64": 0.27.7 + "@esbuild/linux-mips64el": 0.27.7 + "@esbuild/linux-ppc64": 0.27.7 + "@esbuild/linux-riscv64": 0.27.7 + "@esbuild/linux-s390x": 0.27.7 + "@esbuild/linux-x64": 0.27.7 + "@esbuild/netbsd-arm64": 0.27.7 + "@esbuild/netbsd-x64": 0.27.7 + "@esbuild/openbsd-arm64": 0.27.7 + "@esbuild/openbsd-x64": 0.27.7 + "@esbuild/openharmony-arm64": 0.27.7 + "@esbuild/sunos-x64": 0.27.7 + "@esbuild/win32-arm64": 0.27.7 + "@esbuild/win32-ia32": 0.27.7 + "@esbuild/win32-x64": 0.27.7 + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: ea7ee3c039b83caae1b59bb7ae2db9c6bceb21bccb033dbc4c0c45cb159554ead4289492ad874857bbca7f6e37bf74e04e892544de2b3c5c7888c8ef8beaf2f7 + languageName: node + linkType: hard + "escape-string-regexp@npm:^5.0.0": version: 5.0.0 resolution: "escape-string-regexp@npm:5.0.0" @@ -2587,6 +2974,13 @@ __metadata: languageName: node linkType: hard +"exponential-backoff@npm:^3.1.1": + version: 3.1.3 + resolution: "exponential-backoff@npm:3.1.3" + checksum: 471fdb70fd3d2c08a74a026973bdd4105b7832911f610ca67bbb74e39279411c1eed2f2a110c9d41c2edd89459ba58fdaba1c174beed73e7a42d773882dcff82 + languageName: node + linkType: hard + "exsolve@npm:^1.0.7": version: 1.0.8 resolution: "exsolve@npm:1.0.8" @@ -2660,6 +3054,34 @@ __metadata: languageName: node linkType: hard +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: ^7.0.3 + checksum: 8722a41109130851d979222d3ec88aabaceeaaf8f57b2a8f744ef8bd2d1ce95453b04a61daa0078822bc5cd21e008814f06fe6586f56fef511e71b8d2394d802 + languageName: node + linkType: hard + +"fsevents@npm:~2.3.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: latest + checksum: 11e6ea6fea15e42461fc55b4b0e4a0a3c654faa567f1877dbd353f39156f69def97a69936d1746619d656c4b93de2238bf731f6085a03a50cabf287c9d024317 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@~2.3.3#~builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=18f3a7" + dependencies: + node-gyp: latest + conditions: os=darwin + languageName: node + linkType: hard + "get-stream@npm:^8.0.1": version: 8.0.1 resolution: "get-stream@npm:8.0.1" @@ -2667,6 +3089,15 @@ __metadata: languageName: node linkType: hard +"get-tsconfig@npm:^4.7.5": + version: 4.13.7 + resolution: "get-tsconfig@npm:4.13.7" + dependencies: + resolve-pkg-maps: ^1.0.0 + checksum: fa00f90cb0fddd1a4719576d933de416ff6285f6dcf331296dc76434b82bc90e639fdc2c256888771dee154cc128cb9eba9152c76145bd295c9735dd13261967 + languageName: node + linkType: hard + "github-slugger@npm:^2.0.0": version: 2.0.0 resolution: "github-slugger@npm:2.0.0" @@ -2683,6 +3114,17 @@ __metadata: languageName: node linkType: hard +"glob@npm:^13.0.0": + version: 13.0.6 + resolution: "glob@npm:13.0.6" + dependencies: + minimatch: ^10.2.2 + minipass: ^7.1.3 + path-scurry: ^2.0.2 + checksum: 1eb421c696c66af3c26e4845dbdd222d3b982ede17448456b49272722d872e9a91741b50e4e827370c57d17a39a69790061f45033523f085c076d8fcc0f69d2b + languageName: node + linkType: hard + "globals@npm:^15.15.0": version: 15.15.0 resolution: "globals@npm:15.15.0" @@ -2690,7 +3132,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.2.4": +"graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 @@ -2927,6 +3369,33 @@ __metadata: languageName: node linkType: hard +"http-cache-semantics@npm:^4.1.1": + version: 4.2.0 + resolution: "http-cache-semantics@npm:4.2.0" + checksum: 7a7246ddfce629f96832791176fd643589d954e6f3b49548dadb4290451961237fab8fcea41cd2008fe819d95b41c1e8b97f47d088afc0a1c81705287b4ddbcc + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: ^7.1.0 + debug: ^4.3.4 + checksum: 670858c8f8f3146db5889e1fa117630910101db601fff7d5a8aa637da0abedf68c899f03d3451cac2f83bcc4c3d2dabf339b3aa00ff8080571cceb02c3ce02f3 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.6 + resolution: "https-proxy-agent@npm:7.0.6" + dependencies: + agent-base: ^7.1.2 + debug: 4 + checksum: b882377a120aa0544846172e5db021fa8afbf83fea2a897d397bd2ddd8095ab268c24bc462f40a15f2a8c600bf4aa05ce52927f70038d4014e68aefecfa94e8d + languageName: node + linkType: hard + "human-signals@npm:^5.0.0": version: 5.0.0 resolution: "human-signals@npm:5.0.0" @@ -2943,6 +3412,15 @@ __metadata: languageName: node linkType: hard +"iconv-lite@npm:^0.7.2": + version: 0.7.2 + resolution: "iconv-lite@npm:0.7.2" + dependencies: + safer-buffer: ">= 2.1.2 < 3.0.0" + checksum: faf884c1f631a5d676e3e64054bed891c7c5f616b790082d99ccfbfd017c661a39db8009160268fd65fae57c9154d4d491ebc9c301f3446a078460ef114dc4b8 + languageName: node + linkType: hard + "inline-style-parser@npm:0.2.6": version: 0.2.6 resolution: "inline-style-parser@npm:0.2.6" @@ -2964,6 +3442,13 @@ __metadata: languageName: node linkType: hard +"ip-address@npm:^10.0.1": + version: 10.1.0 + resolution: "ip-address@npm:10.1.0" + checksum: 76b1abcdf52a32e2e05ca1f202f3a8ab8547e5651a9233781b330271bd7f1a741067748d71c4cbb9d9906d9f1fa69e7ddc8b4a11130db4534fdab0e908c84e0d + languageName: node + linkType: hard + "is-alphabetical@npm:^2.0.0": version: 2.0.1 resolution: "is-alphabetical@npm:2.0.1" @@ -3077,6 +3562,13 @@ __metadata: languageName: node linkType: hard +"isexe@npm:^4.0.0": + version: 4.0.0 + resolution: "isexe@npm:4.0.0" + checksum: 2ead327ef596042ef9c9ec5f236b316acfaedb87f4bb61b3c3d574fb2e9c8a04b67305e04733bde52c24d9622fdebd3270aadb632adfbf9cadef88fe30f479e5 + languageName: node + linkType: hard + "jiti@npm:^2.6.1": version: 2.6.1 resolution: "jiti@npm:2.6.1" @@ -3283,6 +3775,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1": + version: 11.2.7 + resolution: "lru-cache@npm:11.2.7" + checksum: c4aba67de4a8566622eb1e99cc5f43c1f91129c941af7624d4bbd48f312525d4bf4ce808a414d658a6bc336f0163daa1098d3a3e736989ad65d3231f587fbc30 + languageName: node + linkType: hard + "magic-string@npm:^0.30.21": version: 0.30.21 resolution: "magic-string@npm:0.30.21" @@ -3292,6 +3791,26 @@ __metadata: languageName: node linkType: hard +"make-fetch-happen@npm:^15.0.0": + version: 15.0.5 + resolution: "make-fetch-happen@npm:15.0.5" + dependencies: + "@gar/promise-retry": ^1.0.0 + "@npmcli/agent": ^4.0.0 + "@npmcli/redact": ^4.0.0 + cacache: ^20.0.1 + http-cache-semantics: ^4.1.1 + minipass: ^7.0.2 + minipass-fetch: ^5.0.0 + minipass-flush: ^1.0.5 + minipass-pipeline: ^1.2.4 + negotiator: ^1.0.0 + proc-log: ^6.0.0 + ssri: ^13.0.0 + checksum: e43195c1e98d37acb4358eb574e6b4a591cd46624cbb4800ab2988bd21a3e7b4a26f94b561af119637643b87144e2adf03808909fefa4f88122ee1b3af7e9400 + languageName: node + linkType: hard + "markdown-extensions@npm:^2.0.0": version: 2.0.0 resolution: "markdown-extensions@npm:2.0.0" @@ -4118,6 +4637,91 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^10.2.2": + version: 10.2.5 + resolution: "minimatch@npm:10.2.5" + dependencies: + brace-expansion: ^5.0.5 + checksum: 000423875fecbc7da1d74bf63c9081363a71291ef2588c376c45647ac004582cb5bc8cc09ef84420b26bfb490f4d0818d328e78569c6228e20d90271283f73ba + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: ^7.0.3 + checksum: b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^5.0.0": + version: 5.0.2 + resolution: "minipass-fetch@npm:5.0.2" + dependencies: + iconv-lite: ^0.7.2 + minipass: ^7.0.3 + minipass-sized: ^2.0.0 + minizlib: ^3.0.1 + dependenciesMeta: + iconv-lite: + optional: true + checksum: d4dfdd9700fc8aba445834f75f2abaf9e5d404c10eda06e2db4a8ba89fc66a26956d19703d0edf9be864cb30dec22356d343509ad0a105446516c0ead4330328 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.7 + resolution: "minipass-flush@npm:1.0.7" + dependencies: + minipass: ^3.0.0 + checksum: dc43fd1644aaea31b6ba88281d928a136b9fcd5425c718791e1007db15cf2cd41c75d073548d2f46088f90971833b3bd86752d2a2612bf8256122dedf5b7f3db + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: ^3.0.0 + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^2.0.0": + version: 2.0.0 + resolution: "minipass-sized@npm:2.0.0" + dependencies: + minipass: ^7.1.2 + checksum: 1a1fd251aef4e24050a04ea03fdc0514960f7304a374fd01f352bfdb72c0a2c084ad05d63e76011c181cadfb38dbf487f8782e1e778337f6a099ac2da26b6d5d + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: ^4.0.0 + checksum: a30d083c8054cee83cdcdc97f97e4641a3f58ae743970457b1489ce38ee1167b3aaf7d815cd39ec7a99b9c40397fd4f686e83750e73e652b21cb516f6d845e48 + languageName: node + linkType: hard + +"minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3": + version: 7.1.3 + resolution: "minipass@npm:7.1.3" + checksum: 2ede17c0bf8fec499be3360fd07f0ec7666189e3907320a9b653f1530cf84af98928c5b12d80bfb75f321833bf2e97785b940540213ebdafe97a5f10327e664d + languageName: node + linkType: hard + +"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0": + version: 3.1.0 + resolution: "minizlib@npm:3.1.0" + dependencies: + minipass: ^7.1.2 + checksum: a15e6f0128f514b7d41a1c68ce531155447f4669e32d279bba1c1c071ef6c2abd7e4d4579bb59ccc2ed1531346749665968fdd7be8d83eb6b6ae2fe1f3d370a7 + languageName: node + linkType: hard + "mj-context-menu@npm:^0.6.1": version: 0.6.1 resolution: "mj-context-menu@npm:0.6.1" @@ -4310,6 +4914,37 @@ __metadata: languageName: node linkType: hard +"node-gyp@npm:latest": + version: 12.2.0 + resolution: "node-gyp@npm:12.2.0" + dependencies: + env-paths: ^2.2.0 + exponential-backoff: ^3.1.1 + graceful-fs: ^4.2.6 + make-fetch-happen: ^15.0.0 + nopt: ^9.0.0 + proc-log: ^6.0.0 + semver: ^7.3.5 + tar: ^7.5.4 + tinyglobby: ^0.2.12 + which: ^6.0.0 + bin: + node-gyp: bin/node-gyp.js + checksum: d4ce0acd08bd41004f45e10cef468f4bd15eaafb3acc388a0c567416e1746dc005cc080b8a3495e4e2ae2eed170a2123ff622c2d6614062f4a839837dcf1dd9d + languageName: node + linkType: hard + +"nopt@npm:^9.0.0": + version: 9.0.0 + resolution: "nopt@npm:9.0.0" + dependencies: + abbrev: ^4.0.0 + bin: + nopt: bin/nopt.js + checksum: 7a5d9ab0629eaec1944a95438cc4efa6418ed2834aa8eb21a1bea579a7d8ac3e30120131855376a96ef59ab0e23ad8e0bc94d3349770a95e5cb7119339f7c7fb + languageName: node + linkType: hard + "npm-run-path@npm:^5.1.0": version: 5.3.0 resolution: "npm-run-path@npm:5.3.0" @@ -4353,6 +4988,13 @@ __metadata: languageName: node linkType: hard +"p-map@npm:^7.0.2": + version: 7.0.4 + resolution: "p-map@npm:7.0.4" + checksum: 4be2097e942f2fd3a4f4b0c6585c721f23851de8ad6484d20c472b3ea4937d5cd9a59914c832b1bceac7bf9d149001938036b82a52de0bc381f61ff2d35d26a5 + languageName: node + linkType: hard + "package-manager-detector@npm:^1.3.0": version: 1.5.0 resolution: "package-manager-detector@npm:1.5.0" @@ -4462,6 +5104,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^2.0.2": + version: 2.0.2 + resolution: "path-scurry@npm:2.0.2" + dependencies: + lru-cache: ^11.0.0 + minipass: ^7.1.2 + checksum: a723afe86e342e19dd1b49ce4f5b64a9a84b1e2e07ffc62f051c11623ecd461b1bf1599eee1ecacfce03dda8b6bb866a5df80c0ded45375d258ff22f631920a7 + languageName: node + linkType: hard + "pathe@npm:^2.0.1, pathe@npm:^2.0.3": version: 2.0.3 resolution: "pathe@npm:2.0.3" @@ -4551,6 +5203,13 @@ __metadata: languageName: node linkType: hard +"proc-log@npm:^6.0.0": + version: 6.1.0 + resolution: "proc-log@npm:6.1.0" + checksum: ac450ff8244e95b0c9935b52d629fef92ae69b7e39aea19972a8234259614d644402dd62ce9cb094f4a637d8a4514cba90c1456ad785a40ad5b64d502875a817 + languageName: node + linkType: hard + "property-information@npm:^6.0.0": version: 6.5.0 resolution: "property-information@npm:6.5.0" @@ -4870,6 +5529,13 @@ __metadata: languageName: node linkType: hard +"resolve-pkg-maps@npm:^1.0.0": + version: 1.0.0 + resolution: "resolve-pkg-maps@npm:1.0.0" + checksum: 1012afc566b3fdb190a6309cc37ef3b2dcc35dff5fa6683a9d00cd25c3247edfbc4691b91078c97adc82a29b77a2660c30d791d65dab4fc78bfc473f60289977 + languageName: node + linkType: hard + "retext-latin@npm:^4.0.0": version: 4.0.0 resolution: "retext-latin@npm:4.0.0" @@ -4980,6 +5646,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.3.5": + version: 7.7.4 + resolution: "semver@npm:7.7.4" + bin: + semver: bin/semver.js + checksum: 9b4a6a58e98b9723fafcafa393c9d4e8edefaa60b8dfbe39e30892a3604cf1f45f52df9cfb1ae1a22b44c8b3d57fec8a9bb7b3e1645431587cb272399ede152e + languageName: node + linkType: hard + "semver@npm:^7.7.3": version: 7.7.3 resolution: "semver@npm:7.7.3" @@ -5126,6 +5801,34 @@ __metadata: languageName: node linkType: hard +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: b5167a7142c1da704c0e3af85c402002b597081dd9575031a90b4f229ca5678e9a36e8a374f1814c8156a725d17008ae3bde63b92f9cfd132526379e580bec8b + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.5 + resolution: "socks-proxy-agent@npm:8.0.5" + dependencies: + agent-base: ^7.1.2 + debug: ^4.3.4 + socks: ^2.8.3 + checksum: b4fbcdb7ad2d6eec445926e255a1fb95c975db0020543fbac8dfa6c47aecc6b3b619b7fb9c60a3f82c9b2969912a5e7e174a056ae4d98cb5322f3524d6036e1d + languageName: node + linkType: hard + +"socks@npm:^2.8.3": + version: 2.8.7 + resolution: "socks@npm:2.8.7" + dependencies: + ip-address: ^10.0.1 + smart-buffer: ^4.2.0 + checksum: 4bbe2c88cf0eeaf49f94b7f11564a99b2571bde6fd1e714ff95b38f89e1f97858c19e0ab0e6d39eb7f6a984fa67366825895383ed563fe59962a1d57a1d55318 + languageName: node + linkType: hard + "source-map-js@npm:^1.0.2, source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" @@ -5160,6 +5863,15 @@ __metadata: languageName: node linkType: hard +"ssri@npm:^13.0.0": + version: 13.0.1 + resolution: "ssri@npm:13.0.1" + dependencies: + minipass: ^7.0.3 + checksum: 42acbdbd485e9a5a198de2198b6fd474d1e84bff6bea5d95aa0a8aa26ea78ce44f2097ac481e767f0406de7ceccfa4669584116d4fcf2d4e2dba7034d7c34930 + languageName: node + linkType: hard + "stringify-entities@npm:^4.0.0": version: 4.0.4 resolution: "stringify-entities@npm:4.0.4" @@ -5246,6 +5958,19 @@ __metadata: languageName: node linkType: hard +"tar@npm:^7.5.4": + version: 7.5.13 + resolution: "tar@npm:7.5.13" + dependencies: + "@isaacs/fs-minipass": ^4.0.0 + chownr: ^3.0.0 + minipass: ^7.1.2 + minizlib: ^3.1.0 + yallist: ^5.0.0 + checksum: adcc2a9179dab1b36ecb26575e698d2df8491a1df2cc83e2a0fdd8eaefd076da60dd2e20383a37760b5790bee34e9291aa2b2a9b3deef37ff03c1046219e5df7 + languageName: node + linkType: hard + "tinyexec@npm:^1.0.1": version: 1.0.2 resolution: "tinyexec@npm:1.0.2" @@ -5253,7 +5978,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.14": +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.14": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" dependencies: @@ -5323,6 +6048,22 @@ __metadata: languageName: node linkType: hard +"tsx@npm:^4.19.3": + version: 4.21.0 + resolution: "tsx@npm:4.21.0" + dependencies: + esbuild: ~0.27.0 + fsevents: ~2.3.3 + get-tsconfig: ^4.7.5 + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: 50c98e4b6e66d1c30f72925c8e5e7be1a02377574de7cd367d7e7a6d4af43ca8ff659f91c654e7628b25a5498015e32f090529b92c679b0342811e1cf682e8cf + languageName: node + linkType: hard + "twoslash-protocol@npm:0.3.4": version: 0.3.4 resolution: "twoslash-protocol@npm:0.3.4" @@ -5643,6 +6384,17 @@ __metadata: languageName: node linkType: hard +"which@npm:^6.0.0": + version: 6.0.1 + resolution: "which@npm:6.0.1" + dependencies: + isexe: ^4.0.0 + bin: + node-which: bin/which.js + checksum: dbea77c7d3058bf6c78bf9659d2dce4d2b57d39a15b826b2af6ac2e5a219b99dc8a831b79fdbc453c0598adb4f3f84cf9c2491fd52beb9f5d2dececcad117f68 + languageName: node + linkType: hard + "wicked-good-xpath@npm:1.3.0": version: 1.3.0 resolution: "wicked-good-xpath@npm:1.3.0" @@ -5650,6 +6402,20 @@ __metadata: languageName: node linkType: hard +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5 + languageName: node + linkType: hard + +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: eba51182400b9f35b017daa7f419f434424410691bbc5de4f4240cc830fdef906b504424992700dc047f16b4d99100a6f8b8b11175c193f38008e9c96322b6a5 + languageName: node + linkType: hard + "yaml@npm:^2.3.2": version: 2.8.1 resolution: "yaml@npm:2.8.1" From 4b17fed29932525ece0ddc7fff12e295420bd791 Mon Sep 17 00:00:00 2001 From: Krzysztof Polak Date: Fri, 3 Apr 2026 19:31:28 +0200 Subject: [PATCH 3/4] feat: add agent guidelines for project documentation --- AGENTS.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..531c122 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,35 @@ +# Agent Guidelines + +## Language + +- **Code, comments, and file names** — English +- **Documentation content** (`content/`) — English +- **PR titles and descriptions** — English +- **Commit messages** — English + +## Content + +When writing or editing content for this project, follow these rules: + +- Do not use icons in text content. +- Do not use the em dash (-). Use a regular hyphen (-) instead. + +## Project + +This is a [Nextra](https://nextra.site/)-based documentation site for [Codee](https://codee.sh) — a platform built on top of [MedusaJS](https://medusajs.com). + +## Repository structure + +- `content/` — MDX documentation pages +- `app/` — Next.js app directory (layouts, pages, components) +- `app/components/` — Shared React components +- `app/wizard/` — Interactive resource configuration wizard +- `data/` — Static JSON data (resources, solutions) +- `scripts/` — Utility scripts (e.g. fetching resources) + +## Conventions + +- Components: TypeScript (`.tsx`), functional, no class components +- Styling: Tailwind CSS +- Data fetching for static content: scripts in `scripts/`, output to `data/` +- Do not commit `.env*` files From 93807020389d8c2fa5e6fdb50e82cf77fbe58718 Mon Sep 17 00:00:00 2001 From: Krzysztof Polak Date: Fri, 3 Apr 2026 20:50:36 +0200 Subject: [PATCH 4/4] feat: translate wizard component text to English --- app/components/wizard/StepUseCases.tsx | 8 ++++---- app/components/wizard/WizardShell.tsx | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/components/wizard/StepUseCases.tsx b/app/components/wizard/StepUseCases.tsx index fd52ad9..b36fd68 100644 --- a/app/components/wizard/StepUseCases.tsx +++ b/app/components/wizard/StepUseCases.tsx @@ -6,12 +6,12 @@ const USE_CASES: { id: UseCase; label: string; description: string }[] = [ { id: "b2c", label: "B2C", - description: "Sklep dla klientów indywidualnych", + description: "Store for individual customers", }, { id: "b2b", label: "B2B", - description: "Platforma dla klientów biznesowych", + description: "Platform for business customers", }, ]; @@ -32,9 +32,9 @@ export function StepUseCases({ state, onChange }: Props) { return (
-

Jaki sklep chcesz zbudować?

+

What kind of store do you want to build?

- Możesz wybrać oba + You can choose both

diff --git a/app/components/wizard/WizardShell.tsx b/app/components/wizard/WizardShell.tsx index b998e64..0d902ea 100644 --- a/app/components/wizard/WizardShell.tsx +++ b/app/components/wizard/WizardShell.tsx @@ -60,7 +60,7 @@ export function WizardShell() { default: return (
- Krok {step + 1} — wkrótce + Step {step + 1} - coming soon
); }