Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create conscia package #32

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 2 additions & 27 deletions composable-ui/src/components/cms/commerce-connector.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,9 @@
import { Button, Container, Flex, HStack, Text } from '@chakra-ui/react'
import { CommerceConnectorProps, PriceProps } from '@composable/types'
import { ProductCard } from '@composable/ui'
import { useRouter } from 'next/router'

export interface GenericConnectorProps {
title?: string
ctaLabel?: string
ctaHref?: string
ctaHeight?: string
ctaMaxWidth?: string
ctaMinWidth?: string
products?: {
name: string
slug: string
brand?: string
img?: {
url?: string
alt?: string
}
price?: PriceProps
}[]
}

export interface PriceProps {
current: number
currentFormatted: string
regular?: number
regularFormatted?: string
}

export const CommerceConnector = (props: GenericConnectorProps) => {
export const CommerceConnector = (props: CommerceConnectorProps) => {
const {
title,
ctaLabel,
Expand Down
12 changes: 9 additions & 3 deletions composable-ui/src/server/api/routers/cms.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import { createTRPCRouter, publicProcedure } from '../trpc'
import { getPage } from '@composable/cms-generic'
import { PageProps } from '@composable/types'
import { PageSchema } from '@composable/types'
import { z } from 'zod'
import { createTRPCRouter, publicProcedure } from '../trpc'

export const cmsRouter = createTRPCRouter({
getPage: publicProcedure
.input(z.object({ slug: z.string() }))
.query(async ({ input }) => {
return getPage({ pageSlug: input.slug }) as PageProps
try {
const page = await getPage({ pageSlug: input.slug })
return PageSchema.parse(page)
} catch (err) {
console.log(err)
return null
}
}),
})
4 changes: 4 additions & 0 deletions packages/conscia/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: ['custom'],
}
37 changes: 37 additions & 0 deletions packages/conscia/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Integrating Conscia Components into Composable-UI


# Installation and Setup

1. **Navigating to the Project Directory:** Open your terminal and navigate to your local `composable-ui` project directory and then move to `composable-ui` subfolder.
```bash
cd path/to/composable-ui/composable-ui
```
1. **Install the @composable/conscia package**:
```bash
pnpm install @composable/conscia
```
1. **Set the required environment variables:**

```shell
NEXT_PUBLIC_CONSCIA_BASE_URL=https://...conscia.io/api
NEXT_PUBLIC_CONSCIA_TOKEN=
NEXT_PUBLIC_CONSCIA_CUSTOMER_CODE=
```
1. **Update your storefront to use the Conscia data fetching service:**

The `cmsRouter`, defined in `composable-ui/src/server/api/routers/cms.ts`, provides your storefront with a data fetching function called `getPage`, which retrieves the data that is used to populate the content on your storefront. By default this function returns data retrieved from a local file.

In order to use data from Conscia, the `cmsRouter` needs to use the `getPage` data fetching service defined in `@composable/conscia`, instead of from `@composable/cms-generic`. Change the code as follows:


```javascript
// cms.ts - before changes
import { getPage } from '@composable/cms-generic'

...

// cms.ts - after changes
import { getPage } from '@composable/conscia'
```

1 change: 1 addition & 0 deletions packages/conscia/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src'
22 changes: 22 additions & 0 deletions packages/conscia/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@composable/conscia",
"version": "0.0.0",
"main": "./index.ts",
"types": "./index.ts",
"sideEffects": "false",
"scripts": {
"build": "echo \"Build script for @composable/conscia ...\"",
"lint": "eslint \"**/*.{js,ts,tsx}\" --max-warnings 0",
"ts": "tsc --noEmit --incremental"
},
"dependencies": {
"@composable/types": "workspace:*",
"axios": "0.26.1"
},
"devDependencies": {
"@types/node": "^18.6.3",
"eslint-config-custom": "workspace:*",
"tsconfig": "workspace:*",
"typescript": "^4.5.5"
}
}
3 changes: 3 additions & 0 deletions packages/conscia/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './service'
export * from './utils'
export * from './types'
9 changes: 9 additions & 0 deletions packages/conscia/src/service/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import axios from 'axios'

export const consciaClient = axios.create({
baseURL: process.env.NEXT_PUBLIC_CONSCIA_BASE_URL,
headers: {
Authorization: `Bearer ${process.env.NEXT_PUBLIC_CONSCIA_TOKEN}`,
'X-Customer-Code': process.env.NEXT_PUBLIC_CONSCIA_CUSTOMER_CODE ?? '',
},
})
3 changes: 3 additions & 0 deletions packages/conscia/src/service/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './client'
export * from './page'
export * from './templates'
18 changes: 18 additions & 0 deletions packages/conscia/src/service/page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { PageProps } from '@composable/types'
import { ConsciaPageTemplateComponents } from '../types'
import { getTemplateData } from './templates'
import { transformPage } from '../utils'

export const getPage = async ({
pageSlug,
}: {
pageSlug: string
}): Promise<PageProps | null> => {
if (!pageSlug) {
return null
}
const consciaPage = await getTemplateData<ConsciaPageTemplateComponents>({
templateCode: pageSlug,
})
return consciaPage ? transformPage({ consciaPage, pageSlug }) : null
}
18 changes: 18 additions & 0 deletions packages/conscia/src/service/templates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ConsciaComponent, ConsciaTemplate } from '../types'
import { consciaClient } from './client'

export const getTemplateData = async <
Components extends ConsciaComponent<any>
>({
templateCode,
}: {
templateCode: string
}) => {
const response = await consciaClient.post<ConsciaTemplate<Components>>(
'/experience/template/_query',
{
templateCode,
}
)
return response.data
}
126 changes: 126 additions & 0 deletions packages/conscia/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import {
BannerFullProps,
BannerSplitProps,
BannerTextOnlyProps,
CommerceConnectorProps,
CommerceProduct,
GridProps,
TextCardProps,
} from '@composable/types'

export interface ConsciaTemplate<ComponentTypes extends ConsciaComponent<any>> {
duration: number
components: Record<string, ComponentTypes>
errors: any[]
}

export interface ConsciaComponent<ComponentData> {
'@extras': {
rule: {
metadata: any[]
attributes: Record<string, any>
}
}
status: 'VALID' | 'INVALID'
response: ComponentData
}

export type ConsciaHeroBanner = {
__typename: BannerSplitProps['__typename']
containerMarginBottom?: number
containerMarginTop?: number
containerSize: BannerSplitProps['containerSize']
textPosition: string
theme: string
id: BannerSplitProps['id']
content: BannerSplitProps['content']
title: BannerSplitProps['title']
ctaAlphaHref: BannerSplitProps['ctaAlphaHref']
ctaAlphaLabel: BannerSplitProps['ctaAlphaLabel']
image: {
title: string
description: string
url: string
}
}

export type ConsciaCTABanner = {
__typename: BannerFullProps['__typename']
containerMarginBottom?: number
containerMarginTop?: number
containerSize: BannerFullProps['containerSize']
overlayBackground: BannerFullProps['overlayBackground']
textPosition: BannerFullProps['textPosition']
theme: BannerFullProps['theme']
id: BannerFullProps['id']
content: BannerFullProps['content']
title: BannerFullProps['title']
ctaAlphaLabel: BannerFullProps['ctaAlphaLabel']
ctaAlphaHref: BannerFullProps['ctaAlphaHref']
image: {
url: string
title: string
}
linkHref1: BannerFullProps['linkHref1']
linkLabel1: BannerFullProps['linkLabel1']
}

export type ConsciaFeatureCardsHeader = {
__typename: BannerTextOnlyProps['__typename']
centered: BannerTextOnlyProps['centered']
id: BannerTextOnlyProps['id']
content: BannerTextOnlyProps['content']
title: BannerTextOnlyProps['title']
ctaAlphaLabel: BannerTextOnlyProps['ctaAlphaLabel']
ctaAlphaHref: BannerTextOnlyProps['ctaAlphaHref']
}

export interface ConsciaFeaturedProducts {
__typename: CommerceConnectorProps['__typename']
id: CommerceConnectorProps['id']
title: CommerceConnectorProps['title']
containerMarginBottom?: number
containerMarginTop?: number
containerSize: CommerceConnectorProps['containerSize']
ctaMaxWidth: string
ctaMinWidth: string
ctaLabel: CommerceConnectorProps['ctaLabel']
ctaHref: CommerceConnectorProps['ctaHref']
products: (Omit<CommerceProduct, 'img'> & { image: CommerceProduct['img'] })[]
}

export type ConsciaGrid = {
__typename: GridProps['__typename']
id: GridProps['id']
columns: GridProps['columns']
containerMarginBottom?: number
containerMarginTop?: number
gridGap: GridProps['gridGap']
containerSize: GridProps['containerSize']
items: ConsciaTextCard[]
}

export type ConsciaTextCard = {
__typename: TextCardProps['__typename']
id: TextCardProps['id']
title: TextCardProps['title']
image: {
url: string
title: string
}
content: TextCardProps['content']
ctaLabel: TextCardProps['ctaLabel']
ctaHref: TextCardProps['ctaHref']
theme: TextCardProps['theme']
textAlign: TextCardProps['textAlign']
}

export type ConsciaPageTemplateComponents = ConsciaComponent<
| ConsciaHeroBanner
| ConsciaCTABanner
| ConsciaFeatureCardsHeader
| ConsciaFeaturedProducts
| ConsciaGrid
>
export type ConsciaPageTemplateResponse =
ConsciaTemplate<ConsciaPageTemplateComponents>
3 changes: 3 additions & 0 deletions packages/conscia/src/utils/images.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const parseImageUrl = (imageUrl: string) => {
return imageUrl.startsWith('//') ? `https:${imageUrl}` : imageUrl
}
2 changes: 2 additions & 0 deletions packages/conscia/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './images'
export * from './page'
Loading
Loading