Skip to content

Commit 4018d77

Browse files
Merge pull request #359 from gofynd/theme-sections-chunking
section chunking by removing from main bundle React
2 parents 603cfa3 + 7eeb590 commit 4018d77

File tree

7 files changed

+410
-91
lines changed

7 files changed

+410
-91
lines changed

extension-section/src/components/ProductCard.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import styles from '../styles/style.css';
44
export function ProductCard({ product }) {
55
return (
66
<div className={styles.product}>
7-
{product.medias.map((media) => (
7+
{product.media?.map((media) => (
88
<img src={media.url} alt={media.alt} />
99
))}
1010
<h1>{product.name}</h1>

extension-section/src/sections/product-list.jsx

Lines changed: 86 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,107 @@
11
import React, { useEffect } from "react";
2+
import { useGlobalStore, useFPI } from "fdk-core/utils"; // Importing hooks from fdk-core utilities
3+
import { Helmet } from "react-helmet-async"; // Importing Helmet for managing changes to the document head
4+
import styles from "../styles/style.css"; // Importing CSS styles
5+
import { ProductCard } from "../components/ProductCard"; // Importing the ProductCard component
26

3-
import { useGlobalStore, useFPI } from "fdk-core/utils";
4-
import { Helmet } from "react-helmet-async";
5-
import styles from "../styles/style.css";
6-
import { ProductCard } from "../components/ProductCard";
7+
// GraphQL query as a template literal string to fetch products with dynamic variables
8+
const PLP_PRODUCTS = `query products(
9+
$first: Int
10+
$pageNo: Int
11+
$after: String
12+
$pageType: String
13+
) {
14+
products(
15+
first: $first
16+
pageNo: $pageNo
17+
after: $after
18+
pageType: $pageType
19+
) {
20+
page {
21+
current
22+
next_id
23+
has_previous
24+
has_next
25+
item_total
26+
type
27+
size
28+
}
29+
items {
30+
price {
31+
effective {
32+
currency_code
33+
currency_symbol
34+
max
35+
min
36+
}
37+
}
38+
media {
39+
alt
40+
type
41+
url
42+
}
43+
slug
44+
name
45+
}
46+
}
47+
}
48+
`;
749

8-
export function Component({ props }) {
9-
const fpi = useFPI();
10-
const products = useGlobalStore(fpi.getters.PRODUCTS);
50+
// Functional component definition using destructuring to access props
51+
export function Component({ title = 'Extension Title Default' }) {
52+
const fpi = useFPI(); // Using a custom hook to access functional programming interface
53+
const products = useGlobalStore(fpi.getters.PRODUCTS); // Accessing global store to retrieve products
54+
const productItems = products?.items ?? []; // Nullish coalescing operator to handle undefined products
1155

12-
const productItems = products?.data?.items ?? [];
56+
// useEffect to perform side effects, in this case, data fetching
1357
useEffect(() => {
58+
// Checking if productItems is empty and then executing GraphQL query
1459
if (!productItems.length) {
15-
fpi.catalog.getProducts({});
60+
const payload = {
61+
enableFilter: true, // Enabling filter option in the query
62+
first: 12, // Number of products to fetch
63+
pageNo: 1, // Initial page number
64+
pageType: "number", // Type of pagination
65+
};
66+
fpi.executeGQL(PLP_PRODUCTS, payload);
1667
}
17-
}, []);
68+
}, [productItems.length, fpi]); // Dependency array to limit the execution of useEffect
1869

19-
const title = props?.title?.value ?? 'Extension Title Default'
70+
// Conditionally rendering based on the availability of product items
71+
if (!productItems.length) {
72+
return <h2>No Products Found</h2>; // Display message when no products are found
73+
}
2074

2175
return (
2276
<div>
2377
<Helmet>
24-
<title>{ title }</title>
78+
<title>{title}</title> // Setting the title of the page using Helmet
2579
</Helmet>
2680
<h1>Products List</h1>
27-
28-
{!productItems.length ? (
29-
<h2>No Products</h2>
30-
) : (
31-
<div class={styles.container}>
32-
{productItems.map((product) => (
33-
<ProductCard product={product} key={product.slug} />
34-
))}
35-
</div>
36-
)}
81+
<div className={styles.container}>
82+
{productItems.map((product) => (
83+
<ProductCard product={product} key={product.slug} /> // Rendering ProductCard components for each product
84+
))}
85+
</div>
3786
</div>
3887
);
3988
}
4089

41-
Component.serverFetch = ({ fpi }) => fpi.catalog.getProducts({});
90+
// Server-side fetching logic for server-side rendering (SSR)
91+
Component.serverFetch = ({ fpi }) => {
92+
const payload = {
93+
enableFilter: true,
94+
first: 12,
95+
pageNo: 1,
96+
pageType: "number",
97+
};
98+
99+
fpi.custom.setValue("test-extension", true); // Custom settings for the server-side execution context
100+
101+
return fpi.executeGQL(PLP_PRODUCTS, payload); // Executing GraphQL query on the server
102+
};
42103

104+
// Exporting component settings for potential dynamic UI management or configuration panels
43105
export const settings = {
44106
label: "Product List",
45107
name: "product-list",
@@ -49,7 +111,7 @@ export const settings = {
49111
label: "Page Title",
50112
type: "text",
51113
default: "Extension Title",
52-
info: "Page Title",
114+
info: "Set the page title for the product list." // Description for the property
53115
},
54116
],
55117
blocks: [],
Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,49 @@
1+
/* General styles for the product grid */
12
.product {
2-
color: red;
3-
border: 1px solid red
3+
display: flex;
4+
flex-direction: column;
5+
align-items: center;
6+
width: 300px; /* Adjust width as necessary */
7+
padding: 20px;
8+
margin: 20px;
9+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
10+
border-radius: 10px;
11+
background-color: #fff;
12+
transition: transform 0.3s ease-in-out;
13+
}
14+
15+
.product img {
16+
width: 100%; /* Makes images responsive */
17+
height: auto;
18+
border-radius: 5px;
19+
margin-bottom: 10px;
20+
}
21+
22+
.product h1 {
23+
font-size: 18px;
24+
color: #333;
25+
margin: 10px 0;
26+
}
27+
28+
.product h2 {
29+
font-size: 14px;
30+
color: #666;
31+
margin-bottom: 10px;
32+
}
33+
34+
/* Hover effect for product card */
35+
.product:hover {
36+
transform: translateY(-5px);
37+
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);
438
}
39+
40+
/* Container for horizontal product layout */
541
.container {
642
display: flex;
43+
flex-wrap: wrap;
44+
justify-content: center;
45+
gap: 20px;
46+
padding: 20px;
47+
max-width: 1200px;
48+
margin: 0 auto;
749
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@gofynd/fdk-cli",
3-
"version": "7.1.0",
3+
"version": "7.2.0",
44
"main": "index.js",
55
"license": "MIT",
66
"bin": {

src/helper/download.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
import fs from 'fs-extra';
22
import { uninterceptedApiClient } from '../lib/api/ApiClient';
3-
export async function downloadFile(url: string, filePath: string) {
3+
4+
export async function downloadFile(url: string, filePath: string): Promise<void> {
5+
// Ensure the file exists before attempting to write to it
46
fs.ensureFileSync(filePath);
7+
8+
// Create a writable stream to save the downloaded file
59
const writer = fs.createWriteStream(filePath);
610

11+
// Fetch the file as a stream
712
const response = await uninterceptedApiClient.get(url, {
813
responseType: 'stream',
914
});
1015

16+
// Pipe the data stream to the file writer
1117
response.data.pipe(writer);
1218

19+
// Return a promise that resolves when the download is finished or rejects if an error occurs
1320
return new Promise<void>((resolve, reject) => {
14-
writer.on('finish', resolve);
15-
writer.on('error', reject);
21+
writer.on('finish', () => resolve()); // Ensure resolve is called without any arguments
22+
writer.on('error', error => reject(error)); // Directly pass the error to the reject function
1623
});
1724
}

src/helper/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { createDirectory } from './file.utils';
1717
import { DEFAULT_CONTEXT } from '../lib/ThemeContext';
1818
import glob from 'glob'
1919

20-
const FDK_PATH = () => path.join(process.cwd(), '.fdk');
20+
export const FDK_PATH = () => path.join(process.cwd(), '.fdk');
2121
const CONTEXT_PATH = () => path.join(FDK_PATH(), 'context.json');
2222

2323
export type ThemeType = 'react' | 'vue2' | null;

0 commit comments

Comments
 (0)