{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "mjml-react/block-shared",
  "title": "Block Shared",
  "description": "Block Shared email component",
  "dependencies": [
    "@faire/mjml-react",
    "mjml"
  ],
  "registryDependencies": [
    "https://emailcn.run/r/mjml-react/theme-default.json"
  ],
  "files": [
    {
      "path": "registry/bases/mjml-react/blocks/block-shared.tsx",
      "content": "import {\n  Mjml,\n  MjmlAll,\n  MjmlAttributes,\n  MjmlBody,\n  MjmlButton,\n  MjmlColumn,\n  MjmlDivider,\n  MjmlHead,\n  MjmlImage,\n  MjmlPreview,\n  MjmlSection,\n  MjmlText,\n  MjmlWrapper,\n} from \"@faire/mjml-react\";\nimport type { ReactNode } from \"react\";\n\nimport type { EmailTheme } from \"@/components/email/email-theme\";\n\nexport const BlockEmail = ({\n  children,\n  preview,\n  theme,\n}: {\n  children: ReactNode;\n  preview: string;\n  theme: EmailTheme;\n}) => (\n  <Mjml>\n    <MjmlHead>\n      <MjmlPreview>{preview}</MjmlPreview>\n      <MjmlAttributes>\n        <MjmlAll color={theme.colorText} fontFamily={theme.fontFamily} />\n        <MjmlText\n          fontSize={theme.fontSizeBase}\n          lineHeight={theme.lineHeightBase}\n        />\n      </MjmlAttributes>\n    </MjmlHead>\n    <MjmlBody\n      backgroundColor={theme.colorBackground}\n      width={theme.containerWidth}\n    >\n      <MjmlWrapper padding=\"0\">{children}</MjmlWrapper>\n    </MjmlBody>\n  </Mjml>\n);\n\nexport const BlockText = ({\n  align = \"left\",\n  children,\n  color,\n  fontFamily,\n  fontSize,\n  fontWeight,\n  lineHeight,\n  padding = \"0\",\n}: {\n  align?: \"center\" | \"left\" | \"right\";\n  children: ReactNode;\n  color: string;\n  fontFamily: string;\n  fontSize: string;\n  fontWeight?: string;\n  lineHeight: string;\n  padding?: string;\n}) => (\n  <MjmlText\n    align={align}\n    color={color}\n    fontFamily={fontFamily}\n    fontSize={fontSize}\n    fontWeight={fontWeight}\n    lineHeight={lineHeight}\n    padding={padding}\n  >\n    {children}\n  </MjmlText>\n);\n\nexport const BlockHeading = ({\n  align = \"left\",\n  children,\n  theme,\n}: {\n  align?: \"center\" | \"left\" | \"right\";\n  children: ReactNode;\n  theme: EmailTheme;\n}) => (\n  <BlockText\n    align={align}\n    color={theme.colorText}\n    fontFamily={theme.fontFamily}\n    fontSize={theme.fontSizeXl}\n    fontWeight={theme.fontWeightMedium}\n    lineHeight=\"28px\"\n    padding={`0 0 ${theme.spacingBase}`}\n  >\n    {children}\n  </BlockText>\n);\n\nexport const BlockParagraph = ({\n  align = \"left\",\n  children,\n  padding = \"0 0 16px\",\n  theme,\n}: {\n  align?: \"center\" | \"left\" | \"right\";\n  children: ReactNode;\n  padding?: string;\n  theme: EmailTheme;\n}) => (\n  <BlockText\n    align={align}\n    color={theme.colorTextMuted}\n    fontFamily={theme.fontFamily}\n    fontSize={theme.fontSizeLg}\n    lineHeight={theme.lineHeightBase}\n    padding={padding}\n  >\n    {children}\n  </BlockText>\n);\n\nexport const BlockAction = ({\n  align = \"left\",\n  href,\n  label,\n  theme,\n}: {\n  align?: \"center\" | \"left\" | \"right\";\n  href: string;\n  label: string;\n  theme: EmailTheme;\n}) => (\n  <MjmlButton\n    align={align}\n    backgroundColor={theme.colorPrimary}\n    borderRadius={theme.button.primary.borderRadius}\n    color={theme.colorPrimaryForeground}\n    fontFamily={theme.fontFamily}\n    fontSize={theme.button.primary.fontSize}\n    fontWeight={theme.button.primary.fontWeight}\n    href={href}\n    innerPadding={`${theme.button.primary.paddingY} ${theme.button.primary.paddingX}`}\n    padding={`${theme.spacingBase} 0`}\n  >\n    {label}\n  </MjmlButton>\n);\n\nexport const BlockCode = ({\n  code,\n  theme,\n}: {\n  code: string;\n  theme: EmailTheme;\n}) => (\n  <MjmlSection\n    backgroundColor={theme.colorBackgroundMuted}\n    borderRadius={theme.borderRadius}\n    padding=\"24px 32px\"\n  >\n    <MjmlColumn>\n      <BlockText\n        align=\"center\"\n        color={theme.colorText}\n        fontFamily={theme.fontFamilyMono}\n        fontSize=\"32px\"\n        fontWeight={theme.fontWeightBold}\n        lineHeight=\"40px\"\n      >\n        {code}\n      </BlockText>\n    </MjmlColumn>\n  </MjmlSection>\n);\n\nexport const BlockCard = ({\n  children,\n  theme,\n}: {\n  children: ReactNode;\n  theme: EmailTheme;\n}) => (\n  <MjmlSection\n    backgroundColor={theme.colorBackgroundMuted}\n    border={`1px solid ${theme.colorBorder}`}\n    borderRadius={theme.borderRadiusLg}\n    padding=\"24px\"\n  >\n    <MjmlColumn>{children}</MjmlColumn>\n  </MjmlSection>\n);\n\nexport const BlockFooter = ({\n  children,\n  theme,\n}: {\n  children: ReactNode;\n  theme: EmailTheme;\n}) => (\n  <MjmlSection padding={`${theme.spacingLg} 0 ${theme.spacingBase}`}>\n    <MjmlColumn>\n      <MjmlDivider borderColor={theme.colorBorder} padding=\"0 0 20px\" />\n      <BlockText\n        color={theme.colorTextSubtle}\n        fontFamily={theme.fontFamily}\n        fontSize={theme.fontSizeSm}\n        lineHeight=\"18px\"\n      >\n        {children}\n      </BlockText>\n    </MjmlColumn>\n  </MjmlSection>\n);\n\nexport const BlockLogo = ({\n  alt,\n  href = \"https://example.com\",\n  src,\n}: {\n  alt: string;\n  href?: string;\n  src?: string;\n}) =>\n  src ? (\n    <MjmlImage\n      align=\"left\"\n      alt={alt}\n      href={href}\n      padding=\"0 0 24px\"\n      src={src}\n      width=\"120px\"\n    />\n  ) : null;\n\nexport const AuthOtpBlock = ({\n  expiresInMinutes,\n  otpCode,\n  productName,\n  theme,\n}: {\n  expiresInMinutes: number;\n  otpCode: string;\n  productName: string;\n  theme: EmailTheme;\n}) => (\n  <BlockEmail preview=\"Your verification code\" theme={theme}>\n    <MjmlSection padding={`${theme.spacingXl} 0 ${theme.spacingBase}`}>\n      <MjmlColumn>\n        <BlockHeading theme={theme}>Your verification code</BlockHeading>\n        <BlockParagraph theme={theme}>\n          Enter this code to sign in to your {productName} account. This code\n          expires in {expiresInMinutes} minutes.\n        </BlockParagraph>\n      </MjmlColumn>\n    </MjmlSection>\n    <BlockCode code={otpCode} theme={theme} />\n    <BlockFooter theme={theme}>\n      If you didn’t request this, you can safely ignore this email.\n    </BlockFooter>\n  </BlockEmail>\n);\n\nexport const PasswordResetBlock = ({\n  expiresInMinutes,\n  productName,\n  resetHref,\n  theme,\n}: {\n  expiresInMinutes: number;\n  productName: string;\n  resetHref: string;\n  theme: EmailTheme;\n}) => (\n  <BlockEmail preview=\"Reset your password\" theme={theme}>\n    <MjmlSection padding={`${theme.spacingXl} 0 ${theme.spacingBase}`}>\n      <MjmlColumn>\n        <BlockHeading theme={theme}>Reset your password</BlockHeading>\n        <BlockParagraph theme={theme}>\n          Click the button below to reset your {productName} password. This link\n          expires in {expiresInMinutes} minutes.\n        </BlockParagraph>\n        <BlockAction href={resetHref} label=\"Reset password\" theme={theme} />\n      </MjmlColumn>\n    </MjmlSection>\n    <BlockFooter theme={theme}>\n      If you didn’t request this, you can safely ignore this email.\n    </BlockFooter>\n  </BlockEmail>\n);\n\nexport const InviteBlock = ({\n  ctaHref,\n  expiresInHours,\n  inviterAvatarUrl,\n  inviterName,\n  teamName,\n  theme,\n}: {\n  ctaHref: string;\n  expiresInHours: number;\n  inviterAvatarUrl?: string;\n  inviterName: string;\n  teamName: string;\n  theme: EmailTheme;\n}) => (\n  <BlockEmail preview={`You’re invited to join ${teamName}`} theme={theme}>\n    <MjmlSection padding={`${theme.spacingXl} 0 ${theme.spacingBase}`}>\n      {inviterAvatarUrl ? (\n        <MjmlColumn width=\"72px\">\n          <MjmlImage\n            align=\"left\"\n            alt={inviterName}\n            borderRadius=\"28px\"\n            padding=\"0\"\n            src={inviterAvatarUrl}\n            width=\"56px\"\n          />\n        </MjmlColumn>\n      ) : null}\n      <MjmlColumn>\n        <BlockText\n          color={theme.colorText}\n          fontFamily={theme.fontFamily}\n          fontSize={theme.fontSizeLg}\n          fontWeight={theme.fontWeightMedium}\n          lineHeight={theme.lineHeightBase}\n        >\n          {inviterName}\n        </BlockText>\n        <BlockParagraph padding=\"4px 0 24px\" theme={theme}>\n          invited you to join\n        </BlockParagraph>\n        <BlockHeading theme={theme}>{teamName}</BlockHeading>\n        <BlockParagraph theme={theme}>\n          Click the button below to accept this invitation and join the team.\n          This invitation expires in {expiresInHours} hours.\n        </BlockParagraph>\n        <BlockAction href={ctaHref} label={`Join ${teamName}`} theme={theme} />\n      </MjmlColumn>\n    </MjmlSection>\n    <BlockFooter theme={theme}>\n      If you didn’t expect this invitation, you can ignore this email.\n    </BlockFooter>\n  </BlockEmail>\n);\n\nexport interface NewsletterArticle {\n  title: string;\n  summary: string;\n  href: string;\n  imageUrl?: string;\n}\n\nexport const NewsletterBlock = ({\n  articles,\n  issueNumber,\n  preheader,\n  productName,\n  theme,\n}: {\n  articles: NewsletterArticle[];\n  issueNumber: string;\n  preheader: string;\n  productName: string;\n  theme: EmailTheme;\n}) => (\n  <BlockEmail preview={preheader} theme={theme}>\n    <MjmlSection padding={`${theme.spacingXl} 0 ${theme.spacingBase}`}>\n      <MjmlColumn>\n        <BlockText\n          color={theme.colorTextMuted}\n          fontFamily={theme.fontFamily}\n          fontSize={theme.fontSizeSm}\n          lineHeight=\"18px\"\n        >\n          Issue #{issueNumber}\n        </BlockText>\n        <BlockText\n          color={theme.colorText}\n          fontFamily={theme.fontFamily}\n          fontSize={theme.fontSizeHeading}\n          fontWeight={theme.fontWeightBold}\n          lineHeight=\"36px\"\n          padding=\"8px 0 0\"\n        >\n          {productName}\n        </BlockText>\n      </MjmlColumn>\n    </MjmlSection>\n    <MjmlSection padding=\"0 0 16px\">\n      <MjmlColumn>\n        <BlockHeading theme={theme}>Featured articles</BlockHeading>\n      </MjmlColumn>\n    </MjmlSection>\n    {articles.map((article) => (\n      <MjmlSection\n        backgroundColor={theme.colorBackgroundMuted}\n        borderRadius={theme.borderRadius}\n        key={`${article.title}-${article.href}`}\n        padding=\"20px 24px\"\n      >\n        {article.imageUrl ? (\n          <MjmlColumn width=\"32%\">\n            <MjmlImage\n              alt={article.title}\n              borderRadius={theme.borderRadius}\n              href={article.href}\n              padding=\"0 16px 0 0\"\n              src={article.imageUrl}\n            />\n          </MjmlColumn>\n        ) : null}\n        <MjmlColumn width={article.imageUrl ? \"68%\" : \"100%\"}>\n          <BlockText\n            color={theme.colorText}\n            fontFamily={theme.fontFamily}\n            fontSize={theme.fontSizeLg}\n            fontWeight={theme.fontWeightMedium}\n            lineHeight=\"24px\"\n          >\n            {article.title}\n          </BlockText>\n          <BlockParagraph padding=\"8px 0\" theme={theme}>\n            {article.summary}\n          </BlockParagraph>\n          <MjmlButton\n            align=\"left\"\n            backgroundColor=\"transparent\"\n            color={theme.colorPrimary}\n            fontFamily={theme.fontFamily}\n            fontSize={theme.fontSizeBase}\n            href={article.href}\n            innerPadding=\"0\"\n            padding=\"0\"\n          >\n            Read article\n          </MjmlButton>\n        </MjmlColumn>\n      </MjmlSection>\n    ))}\n    <BlockFooter theme={theme}>\n      View this email online · Unsubscribe\n    </BlockFooter>\n  </BlockEmail>\n);\n\nexport const NotificationBlock = ({\n  action,\n  actorAvatarUrl,\n  actorName,\n  body,\n  ctaHref,\n  ctaLabel,\n  heading,\n  issueNumber,\n  preview = \"New notification\",\n  targetName,\n  theme,\n}: {\n  action?: string;\n  actorAvatarUrl?: string;\n  actorName?: string;\n  body?: string;\n  ctaHref: string;\n  ctaLabel: string;\n  heading: string;\n  issueNumber?: string;\n  preview?: string;\n  targetName?: string;\n  theme: EmailTheme;\n}) => (\n  <BlockEmail preview={preview} theme={theme}>\n    <MjmlSection padding={`${theme.spacingXl} 0 ${theme.spacingBase}`}>\n      {actorAvatarUrl ? (\n        <MjmlColumn width=\"64px\">\n          <MjmlImage\n            alt={actorName}\n            borderRadius=\"24px\"\n            padding=\"0 16px 0 0\"\n            src={actorAvatarUrl}\n            width=\"48px\"\n          />\n        </MjmlColumn>\n      ) : null}\n      <MjmlColumn>\n        {actorName ? (\n          <BlockText\n            color={theme.colorText}\n            fontFamily={theme.fontFamily}\n            fontSize={theme.fontSizeLg}\n            fontWeight={theme.fontWeightMedium}\n            lineHeight={theme.lineHeightBase}\n          >\n            {actorName}\n          </BlockText>\n        ) : null}\n        {action ? (\n          <BlockParagraph padding=\"4px 0 20px\" theme={theme}>\n            {action}\n          </BlockParagraph>\n        ) : null}\n        <BlockHeading theme={theme}>\n          {issueNumber ? `#${issueNumber} · ` : \"\"}\n          {heading}\n        </BlockHeading>\n        {targetName ? (\n          <BlockParagraph theme={theme}>{targetName}</BlockParagraph>\n        ) : null}\n        {body ? <BlockParagraph theme={theme}>{body}</BlockParagraph> : null}\n        {ctaHref && ctaLabel ? (\n          <BlockAction href={ctaHref} label={ctaLabel} theme={theme} />\n        ) : null}\n      </MjmlColumn>\n    </MjmlSection>\n  </BlockEmail>\n);\n\nexport const OnboardingBlock = ({\n  ctaHref,\n  firstName,\n  productName,\n  senderName,\n  theme,\n}: {\n  ctaHref: string;\n  firstName: string;\n  productName: string;\n  senderName: string;\n  theme: EmailTheme;\n}) => (\n  <BlockEmail preview={`Welcome to ${productName}, ${firstName}`} theme={theme}>\n    <MjmlSection padding={`${theme.spacingBase} 0`}>\n      <MjmlColumn>\n        <BlockText\n          color={theme.colorText}\n          fontFamily={theme.fontFamily}\n          fontSize={theme.fontSizeLg}\n          fontWeight={theme.fontWeightBold}\n          lineHeight=\"24px\"\n        >\n          {productName}\n        </BlockText>\n      </MjmlColumn>\n    </MjmlSection>\n    <MjmlSection\n      backgroundColor={theme.colorBackgroundMuted}\n      borderRadius={theme.borderRadiusLg}\n      padding={`${theme.spacingXl} ${theme.spacingLg}`}\n    >\n      <MjmlColumn>\n        <BlockText\n          align=\"center\"\n          color={theme.colorText}\n          fontFamily={theme.fontFamily}\n          fontSize={theme.fontSizeHeading}\n          fontWeight={theme.fontWeightBold}\n          lineHeight=\"36px\"\n        >\n          Welcome, {firstName}\n        </BlockText>\n        <BlockParagraph align=\"center\" padding=\"16px 0 4px\" theme={theme}>\n          We’re excited to have you on board at {productName}. Let’s get you set\n          up for success.\n        </BlockParagraph>\n        <BlockAction\n          align=\"center\"\n          href={ctaHref}\n          label=\"Get started\"\n          theme={theme}\n        />\n      </MjmlColumn>\n    </MjmlSection>\n    <MjmlSection padding={`${theme.spacingLg} 0`}>\n      {[\n        \"Create your profile\",\n        \"Explore your workspace\",\n        \"Invite your team\",\n      ].map((step, index) => (\n        <MjmlColumn key={step} padding=\"8px\" width=\"33.333%\">\n          <BlockText\n            align=\"center\"\n            color={theme.colorPrimary}\n            fontFamily={theme.fontFamilyMono}\n            fontSize={theme.fontSizeXl}\n            fontWeight={theme.fontWeightBold}\n            lineHeight=\"28px\"\n          >\n            0{index + 1}\n          </BlockText>\n          <BlockText\n            align=\"center\"\n            color={theme.colorText}\n            fontFamily={theme.fontFamily}\n            fontSize={theme.fontSizeBase}\n            fontWeight={theme.fontWeightMedium}\n            lineHeight=\"20px\"\n            padding=\"8px 0 0\"\n          >\n            {step}\n          </BlockText>\n        </MjmlColumn>\n      ))}\n    </MjmlSection>\n    <BlockFooter theme={theme}>Sent by {senderName}</BlockFooter>\n  </BlockEmail>\n);\n\nexport interface NativeReceiptItem {\n  name: string;\n  imageUrl?: string;\n  price: string;\n  quantity?: number;\n}\n\nconst ReceiptTotalRow = ({\n  bold = false,\n  label,\n  theme,\n  value,\n}: {\n  bold?: boolean;\n  label: string;\n  theme: EmailTheme;\n  value: string;\n}) => (\n  <>\n    <MjmlColumn width=\"50%\">\n      <BlockText\n        color={bold ? theme.colorText : theme.colorTextMuted}\n        fontFamily={theme.fontFamily}\n        fontSize={bold ? theme.fontSizeLg : theme.fontSizeBase}\n        fontWeight={bold ? theme.fontWeightBold : theme.fontWeightNormal}\n        lineHeight=\"24px\"\n        padding=\"4px 0\"\n      >\n        {label}\n      </BlockText>\n    </MjmlColumn>\n    <MjmlColumn width=\"50%\">\n      <BlockText\n        align=\"right\"\n        color={theme.colorText}\n        fontFamily={theme.fontFamily}\n        fontSize={bold ? theme.fontSizeLg : theme.fontSizeBase}\n        fontWeight={bold ? theme.fontWeightBold : theme.fontWeightMedium}\n        lineHeight=\"24px\"\n        padding=\"4px 0\"\n      >\n        {value}\n      </BlockText>\n    </MjmlColumn>\n  </>\n);\n\nexport const ReceiptBlock = ({\n  customerName,\n  items,\n  label = \"Receipt\",\n  orderNumber,\n  subtotal,\n  supportHref,\n  supportLabel = \"Contact support\",\n  tax,\n  theme,\n  total,\n}: {\n  customerName: string;\n  items: NativeReceiptItem[];\n  label?: string;\n  orderNumber: string;\n  subtotal: string;\n  supportHref: string;\n  supportLabel?: string;\n  tax: string;\n  theme: EmailTheme;\n  total: string;\n}) => (\n  <BlockEmail preview={`Your ${label.toLowerCase()}`} theme={theme}>\n    <MjmlSection padding={`${theme.spacingXl} 0 ${theme.spacingBase}`}>\n      <MjmlColumn>\n        <BlockText\n          color={theme.colorText}\n          fontFamily={theme.fontFamily}\n          fontSize={theme.fontSizeHeading}\n          fontWeight={theme.fontWeightBold}\n          lineHeight=\"36px\"\n        >\n          {label}\n        </BlockText>\n        <BlockParagraph padding=\"6px 0 16px\" theme={theme}>\n          {label === \"Receipt\" ? \"Order \" : \"\"}\n          {orderNumber} · {customerName}\n        </BlockParagraph>\n      </MjmlColumn>\n    </MjmlSection>\n    {items.map((item, index) => (\n      <MjmlSection\n        backgroundColor={theme.colorBackgroundMuted}\n        borderRadius={theme.borderRadius}\n        key={`${item.name}-${index}`}\n        padding=\"16px\"\n      >\n        {item.imageUrl ? (\n          <MjmlColumn width=\"24%\">\n            <MjmlImage\n              alt={item.name}\n              borderRadius={theme.borderRadius}\n              padding=\"0 16px 0 0\"\n              src={item.imageUrl}\n              width=\"88px\"\n            />\n          </MjmlColumn>\n        ) : null}\n        <MjmlColumn width={item.imageUrl ? \"51%\" : \"75%\"}>\n          <BlockText\n            color={theme.colorText}\n            fontFamily={theme.fontFamily}\n            fontSize={theme.fontSizeLg}\n            fontWeight={theme.fontWeightMedium}\n            lineHeight=\"24px\"\n          >\n            {item.name}\n          </BlockText>\n          <BlockParagraph padding=\"4px 0 0\" theme={theme}>\n            Quantity: {item.quantity ?? 1}\n          </BlockParagraph>\n        </MjmlColumn>\n        <MjmlColumn width=\"25%\">\n          <BlockText\n            align=\"right\"\n            color={theme.colorText}\n            fontFamily={theme.fontFamily}\n            fontSize={theme.fontSizeBase}\n            fontWeight={theme.fontWeightMedium}\n            lineHeight=\"24px\"\n          >\n            {item.price}\n          </BlockText>\n        </MjmlColumn>\n      </MjmlSection>\n    ))}\n    <MjmlSection padding=\"24px 0 0\">\n      <ReceiptTotalRow label=\"Subtotal\" theme={theme} value={subtotal} />\n    </MjmlSection>\n    <MjmlSection padding=\"0\">\n      <ReceiptTotalRow label=\"Tax\" theme={theme} value={tax} />\n    </MjmlSection>\n    <MjmlSection padding=\"0\">\n      <MjmlColumn>\n        <MjmlDivider borderColor={theme.colorBorder} padding=\"12px 0\" />\n      </MjmlColumn>\n    </MjmlSection>\n    <MjmlSection padding=\"0\">\n      <ReceiptTotalRow bold label=\"Total\" theme={theme} value={total} />\n    </MjmlSection>\n    <MjmlSection padding={`${theme.spacingLg} 0`}>\n      <MjmlColumn>\n        <BlockParagraph theme={theme}>Need help?</BlockParagraph>\n        <MjmlButton\n          align=\"left\"\n          backgroundColor=\"transparent\"\n          color={theme.colorText}\n          fontFamily={theme.fontFamily}\n          fontSize={theme.fontSizeBase}\n          href={supportHref}\n          innerPadding=\"0\"\n          padding=\"0\"\n          textDecoration=\"underline\"\n        >\n          {supportLabel}\n        </MjmlButton>\n      </MjmlColumn>\n    </MjmlSection>\n  </BlockEmail>\n);\n",
      "type": "registry:component",
      "target": "components/email/block-shared.tsx"
    }
  ],
  "categories": [
    "email-component"
  ],
  "type": "registry:block"
}