pdf-catalog-generator 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +7 -0
- package/LICENSE +22 -0
- package/README.md +71 -0
- package/dist/generator.d.ts +7 -0
- package/dist/generator.js +130 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +15 -0
- package/dist/parser.d.ts +17 -0
- package/dist/parser.js +93 -0
- package/dist/templates/Template1.d.ts +4 -0
- package/dist/templates/Template1.js +86 -0
- package/dist/templates/Template2.d.ts +4 -0
- package/dist/templates/Template2.js +104 -0
- package/dist/templates/Template3.d.ts +4 -0
- package/dist/templates/Template3.js +85 -0
- package/dist/templates/Template4.d.ts +4 -0
- package/dist/templates/Template4.js +126 -0
- package/dist/templates/index.d.ts +4 -0
- package/dist/templates/index.js +14 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.js +2 -0
- package/package.json +33 -0
- package/pdf-catalog-test/README.md +100 -0
- package/pdf-catalog-test/data/products.csv +8 -0
- package/pdf-catalog-test/data/products.json +51 -0
- package/pdf-catalog-test/data/products.xlsx +0 -0
- package/pdf-catalog-test/package-lock.json +260 -0
- package/pdf-catalog-test/package.json +24 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mohit
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# PDF Catalog Generator
|
|
2
|
+
|
|
3
|
+
Generate beautiful product catalog PDFs from Excel, CSV, or JSON data.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install pdf-catalog-generator
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { generateProductCatalog } from 'pdf-catalog-generator';
|
|
15
|
+
|
|
16
|
+
// From JSON
|
|
17
|
+
const pdfBuffer = await generateProductCatalog({
|
|
18
|
+
products: [
|
|
19
|
+
{
|
|
20
|
+
Title: 'Product 1',
|
|
21
|
+
Description: 'Description here',
|
|
22
|
+
Image: 'https://example.com/image.jpg',
|
|
23
|
+
Price: 99.99,
|
|
24
|
+
Rating: 4.5,
|
|
25
|
+
Link: 'https://example.com/product'
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
companyLogo: 'https://example.com/logo.png', // or base64
|
|
29
|
+
companyName: 'Your Company',
|
|
30
|
+
template: 'template1' // template1, template2, or template3
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// From Excel file
|
|
34
|
+
import { parseExcelFile } from 'pdf-catalog-generator';
|
|
35
|
+
|
|
36
|
+
const products = await parseExcelFile(fileBuffer);
|
|
37
|
+
const pdfBuffer = await generateProductCatalog({
|
|
38
|
+
products,
|
|
39
|
+
companyLogo: logoBase64,
|
|
40
|
+
companyName: 'Your Company',
|
|
41
|
+
template: 'template2'
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// From CSV file
|
|
45
|
+
import { parseCSVFile } from 'pdf-catalog-generator';
|
|
46
|
+
|
|
47
|
+
const products = await parseCSVFile(csvString);
|
|
48
|
+
const pdfBuffer = await generateProductCatalog({
|
|
49
|
+
products,
|
|
50
|
+
companyLogo: logoUrl,
|
|
51
|
+
companyName: 'Your Company',
|
|
52
|
+
template: 'template3'
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Product Data Format
|
|
57
|
+
|
|
58
|
+
Each product should have:
|
|
59
|
+
- `Title` (string): Product name
|
|
60
|
+
- `Description` (string): Product description
|
|
61
|
+
- `Image` (string): Image URL or base64
|
|
62
|
+
- `Price` (number): Product price
|
|
63
|
+
- `Rating` (number): Star rating
|
|
64
|
+
- `Link` (string): Buy/product link
|
|
65
|
+
|
|
66
|
+
## Templates
|
|
67
|
+
|
|
68
|
+
- `template1`: Grid layout with 2 columns
|
|
69
|
+
- `template2`: Full-width list layout
|
|
70
|
+
- `template3`: Compact grid layout
|
|
71
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CatalogConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Generate product catalog PDF
|
|
4
|
+
* @param config Configuration with products, company info, and template choice
|
|
5
|
+
* @returns Promise<Buffer> PDF as Buffer
|
|
6
|
+
*/
|
|
7
|
+
export declare function generateProductCatalog(config: CatalogConfig): Promise<Buffer>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateProductCatalog = generateProductCatalog;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const renderer_1 = require("@react-pdf/renderer");
|
|
9
|
+
const templates_1 = require("./templates");
|
|
10
|
+
// Create styles
|
|
11
|
+
const styles = renderer_1.StyleSheet.create({
|
|
12
|
+
page: {
|
|
13
|
+
flexDirection: 'column',
|
|
14
|
+
backgroundColor: '#FFFFFF',
|
|
15
|
+
},
|
|
16
|
+
header: {
|
|
17
|
+
height: '100vh',
|
|
18
|
+
display: 'flex',
|
|
19
|
+
flexDirection: 'row',
|
|
20
|
+
alignItems: 'center',
|
|
21
|
+
alignContent: 'center',
|
|
22
|
+
padding: 10,
|
|
23
|
+
marginBottom: 5,
|
|
24
|
+
},
|
|
25
|
+
logoSection: {
|
|
26
|
+
width: '80%',
|
|
27
|
+
},
|
|
28
|
+
storeNameSection: {},
|
|
29
|
+
logo: {
|
|
30
|
+
marginRight: 10,
|
|
31
|
+
objectFit: 'contain',
|
|
32
|
+
},
|
|
33
|
+
storeName: {
|
|
34
|
+
fontSize: 35,
|
|
35
|
+
flexGrow: 1,
|
|
36
|
+
transform: 'rotate(-90deg)',
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
// Register emoji support
|
|
40
|
+
renderer_1.Font.registerEmojiSource({
|
|
41
|
+
format: 'png',
|
|
42
|
+
url: 'https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/',
|
|
43
|
+
});
|
|
44
|
+
/**
|
|
45
|
+
* Normalize image source for react-pdf Image component
|
|
46
|
+
* Handles URLs, data URIs, and plain base64 strings
|
|
47
|
+
* @param imageSource Image source string (URL, data URI, or base64)
|
|
48
|
+
* @returns Normalized image source string
|
|
49
|
+
*/
|
|
50
|
+
function normalizeImageSource(imageSource) {
|
|
51
|
+
// If already a data URI, return as-is
|
|
52
|
+
if (imageSource.startsWith('data:')) {
|
|
53
|
+
return imageSource;
|
|
54
|
+
}
|
|
55
|
+
// If it's a URL, return as-is
|
|
56
|
+
if (imageSource.startsWith('http://') || imageSource.startsWith('https://')) {
|
|
57
|
+
return imageSource;
|
|
58
|
+
}
|
|
59
|
+
// Otherwise, assume it's a base64 string and convert to data URI
|
|
60
|
+
// Try to detect image type from common base64 patterns
|
|
61
|
+
let mimeType = 'image/png'; // default
|
|
62
|
+
// Check for common base64 image signatures
|
|
63
|
+
// PNG: starts with iVBORw0KGgo
|
|
64
|
+
// JPEG: starts with /9j/4AAQ
|
|
65
|
+
// GIF: starts with R0lGODlh
|
|
66
|
+
// WebP: starts with UklGR
|
|
67
|
+
const base64Start = imageSource.substring(0, 20).toLowerCase();
|
|
68
|
+
if (base64Start.includes('ivborw0kggo') || imageSource.startsWith('iVBORw0KGgo')) {
|
|
69
|
+
mimeType = 'image/png';
|
|
70
|
+
}
|
|
71
|
+
else if (base64Start.includes('/9j/4aaq') || imageSource.startsWith('/9j/4AAQ')) {
|
|
72
|
+
mimeType = 'image/jpeg';
|
|
73
|
+
}
|
|
74
|
+
else if (base64Start.includes('r0lgodlh') || imageSource.startsWith('R0lGODlh')) {
|
|
75
|
+
mimeType = 'image/gif';
|
|
76
|
+
}
|
|
77
|
+
else if (base64Start.includes('uklgr') || imageSource.startsWith('UklGR')) {
|
|
78
|
+
mimeType = 'image/webp';
|
|
79
|
+
}
|
|
80
|
+
return `data:${mimeType};base64,${imageSource}`;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Generate product catalog PDF
|
|
84
|
+
* @param config Configuration with products, company info, and template choice
|
|
85
|
+
* @returns Promise<Buffer> PDF as Buffer
|
|
86
|
+
*/
|
|
87
|
+
async function generateProductCatalog(config) {
|
|
88
|
+
const { products, companyLogo, companyName, template = 'template1', } = config;
|
|
89
|
+
// Select template component
|
|
90
|
+
let TemplateComponent;
|
|
91
|
+
switch (template) {
|
|
92
|
+
case 'template1':
|
|
93
|
+
TemplateComponent = templates_1.Template1;
|
|
94
|
+
break;
|
|
95
|
+
case 'template2':
|
|
96
|
+
TemplateComponent = templates_1.Template2;
|
|
97
|
+
break;
|
|
98
|
+
case 'template3':
|
|
99
|
+
TemplateComponent = templates_1.Template3;
|
|
100
|
+
break;
|
|
101
|
+
case 'template4':
|
|
102
|
+
TemplateComponent = templates_1.Template4;
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
TemplateComponent = templates_1.Template1;
|
|
106
|
+
}
|
|
107
|
+
// Template4 handles its own page layout with headers on each page
|
|
108
|
+
if (template === 'template4') {
|
|
109
|
+
const doc = (react_1.default.createElement(renderer_1.Document, null,
|
|
110
|
+
react_1.default.createElement(renderer_1.Page, { size: "A4", style: styles.page },
|
|
111
|
+
react_1.default.createElement(templates_1.Template4, { products: products, companyLogo: companyLogo ? normalizeImageSource(companyLogo) : undefined, companyName: companyName }))));
|
|
112
|
+
const blob = await (0, renderer_1.pdf)(doc).toBlob();
|
|
113
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
114
|
+
return Buffer.from(arrayBuffer);
|
|
115
|
+
}
|
|
116
|
+
// Create PDF document for other templates
|
|
117
|
+
const doc = (react_1.default.createElement(renderer_1.Document, null,
|
|
118
|
+
react_1.default.createElement(renderer_1.Page, { size: "A4", style: styles.page },
|
|
119
|
+
react_1.default.createElement(renderer_1.View, { style: styles.header },
|
|
120
|
+
companyLogo && (react_1.default.createElement(renderer_1.View, { style: styles.logoSection },
|
|
121
|
+
react_1.default.createElement(renderer_1.Image, { style: styles.logo, src: normalizeImageSource(companyLogo) }))),
|
|
122
|
+
react_1.default.createElement(renderer_1.View, { style: styles.storeNameSection },
|
|
123
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.storeName }, companyName)),
|
|
124
|
+
react_1.default.createElement(renderer_1.View, { break: true })),
|
|
125
|
+
react_1.default.createElement(TemplateComponent, { products: products }))));
|
|
126
|
+
// Generate PDF and return as Buffer
|
|
127
|
+
const blob = await (0, renderer_1.pdf)(doc).toBlob();
|
|
128
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
129
|
+
return Buffer.from(arrayBuffer);
|
|
130
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { generateProductCatalog } from './generator';
|
|
2
|
+
export { parseExcelFile, parseCSVFile, parseCSVBuffer, parseJSON, } from './parser';
|
|
3
|
+
export { Template1, Template2, Template3, Template4 } from './templates';
|
|
4
|
+
export type { ProductData, CatalogConfig, TemplateProps, TemplateType, } from './types';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Template4 = exports.Template3 = exports.Template2 = exports.Template1 = exports.parseJSON = exports.parseCSVBuffer = exports.parseCSVFile = exports.parseExcelFile = exports.generateProductCatalog = void 0;
|
|
4
|
+
var generator_1 = require("./generator");
|
|
5
|
+
Object.defineProperty(exports, "generateProductCatalog", { enumerable: true, get: function () { return generator_1.generateProductCatalog; } });
|
|
6
|
+
var parser_1 = require("./parser");
|
|
7
|
+
Object.defineProperty(exports, "parseExcelFile", { enumerable: true, get: function () { return parser_1.parseExcelFile; } });
|
|
8
|
+
Object.defineProperty(exports, "parseCSVFile", { enumerable: true, get: function () { return parser_1.parseCSVFile; } });
|
|
9
|
+
Object.defineProperty(exports, "parseCSVBuffer", { enumerable: true, get: function () { return parser_1.parseCSVBuffer; } });
|
|
10
|
+
Object.defineProperty(exports, "parseJSON", { enumerable: true, get: function () { return parser_1.parseJSON; } });
|
|
11
|
+
var templates_1 = require("./templates");
|
|
12
|
+
Object.defineProperty(exports, "Template1", { enumerable: true, get: function () { return templates_1.Template1; } });
|
|
13
|
+
Object.defineProperty(exports, "Template2", { enumerable: true, get: function () { return templates_1.Template2; } });
|
|
14
|
+
Object.defineProperty(exports, "Template3", { enumerable: true, get: function () { return templates_1.Template3; } });
|
|
15
|
+
Object.defineProperty(exports, "Template4", { enumerable: true, get: function () { return templates_1.Template4; } });
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ProductData } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Parse Excel file buffer to product data
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseExcelFile(buffer: Buffer): ProductData[];
|
|
6
|
+
/**
|
|
7
|
+
* Parse CSV string to product data
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseCSVFile(csvString: string): ProductData[];
|
|
10
|
+
/**
|
|
11
|
+
* Parse CSV buffer to product data
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseCSVBuffer(buffer: Buffer): ProductData[];
|
|
14
|
+
/**
|
|
15
|
+
* Validate and normalize product data from JSON
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseJSON(data: any[]): ProductData[];
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parseExcelFile = parseExcelFile;
|
|
37
|
+
exports.parseCSVFile = parseCSVFile;
|
|
38
|
+
exports.parseCSVBuffer = parseCSVBuffer;
|
|
39
|
+
exports.parseJSON = parseJSON;
|
|
40
|
+
const XLSX = __importStar(require("xlsx"));
|
|
41
|
+
/**
|
|
42
|
+
* Parse Excel file buffer to product data
|
|
43
|
+
*/
|
|
44
|
+
function parseExcelFile(buffer) {
|
|
45
|
+
const workbook = XLSX.read(buffer, {
|
|
46
|
+
type: 'buffer',
|
|
47
|
+
cellDates: true,
|
|
48
|
+
});
|
|
49
|
+
const sheetName = workbook.SheetNames[0];
|
|
50
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
51
|
+
const data = XLSX.utils.sheet_to_json(worksheet);
|
|
52
|
+
return data;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Parse CSV string to product data
|
|
56
|
+
*/
|
|
57
|
+
function parseCSVFile(csvString) {
|
|
58
|
+
const workbook = XLSX.read(csvString, {
|
|
59
|
+
type: 'string',
|
|
60
|
+
cellDates: true,
|
|
61
|
+
});
|
|
62
|
+
const sheetName = workbook.SheetNames[0];
|
|
63
|
+
const worksheet = workbook.Sheets[sheetName];
|
|
64
|
+
const data = XLSX.utils.sheet_to_json(worksheet);
|
|
65
|
+
return data;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse CSV buffer to product data
|
|
69
|
+
*/
|
|
70
|
+
function parseCSVBuffer(buffer) {
|
|
71
|
+
return parseCSVFile(buffer.toString('utf-8'));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Validate and normalize product data from JSON
|
|
75
|
+
*/
|
|
76
|
+
function parseJSON(data) {
|
|
77
|
+
if (!Array.isArray(data)) {
|
|
78
|
+
throw new Error('JSON data must be an array of products');
|
|
79
|
+
}
|
|
80
|
+
return data.map((item, index) => {
|
|
81
|
+
if (!item.Title || !item.Link) {
|
|
82
|
+
throw new Error(`Product at index ${index} is missing required fields (Title, Link)`);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
Title: item.Title,
|
|
86
|
+
Description: item.Description || '',
|
|
87
|
+
Image: item.Image || '',
|
|
88
|
+
Price: item.Price || 0,
|
|
89
|
+
Rating: item.Rating || 0,
|
|
90
|
+
Link: item.Link,
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const renderer_1 = require("@react-pdf/renderer");
|
|
8
|
+
const styles = renderer_1.StyleSheet.create({
|
|
9
|
+
productContainer: {
|
|
10
|
+
flexDirection: 'row',
|
|
11
|
+
flexWrap: 'wrap',
|
|
12
|
+
alignItems: 'flex-start',
|
|
13
|
+
justifyContent: 'space-between',
|
|
14
|
+
marginVertical: 50,
|
|
15
|
+
marginHorizontal: 20,
|
|
16
|
+
},
|
|
17
|
+
productSection: {
|
|
18
|
+
width: '48%',
|
|
19
|
+
padding: 10,
|
|
20
|
+
marginBottom: 10,
|
|
21
|
+
backgroundColor: '#f2f2f2',
|
|
22
|
+
borderRadius: 5,
|
|
23
|
+
height: 350,
|
|
24
|
+
display: 'flex',
|
|
25
|
+
flexDirection: 'column',
|
|
26
|
+
justifyContent: 'space-between',
|
|
27
|
+
},
|
|
28
|
+
image: {
|
|
29
|
+
width: '100%',
|
|
30
|
+
height: 200,
|
|
31
|
+
objectFit: 'contain',
|
|
32
|
+
marginBottom: 10,
|
|
33
|
+
},
|
|
34
|
+
productTitleBox: {
|
|
35
|
+
flexDirection: 'row',
|
|
36
|
+
justifyContent: 'space-between',
|
|
37
|
+
},
|
|
38
|
+
productTitle: {
|
|
39
|
+
fontSize: 14,
|
|
40
|
+
fontWeight: 'bold',
|
|
41
|
+
marginBottom: 4,
|
|
42
|
+
},
|
|
43
|
+
productRate: {
|
|
44
|
+
fontWeight: 'bold',
|
|
45
|
+
},
|
|
46
|
+
productPrice: {
|
|
47
|
+
fontSize: 12,
|
|
48
|
+
color: '#2EB62C',
|
|
49
|
+
marginTop: 4,
|
|
50
|
+
marginBottom: 4,
|
|
51
|
+
},
|
|
52
|
+
productDescription: {
|
|
53
|
+
fontSize: 10,
|
|
54
|
+
color: '#555555',
|
|
55
|
+
minHeight: 65,
|
|
56
|
+
marginBottom: 10,
|
|
57
|
+
textAlign: 'justify',
|
|
58
|
+
},
|
|
59
|
+
buyButton: {
|
|
60
|
+
fontSize: 12,
|
|
61
|
+
padding: 8,
|
|
62
|
+
backgroundColor: 'white',
|
|
63
|
+
color: 'black',
|
|
64
|
+
textAlign: 'center',
|
|
65
|
+
borderRadius: 4,
|
|
66
|
+
borderWidth: 1,
|
|
67
|
+
borderColor: '#000000',
|
|
68
|
+
marginTop: 10,
|
|
69
|
+
textDecoration: 'none',
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
const Template1 = ({ products }) => {
|
|
73
|
+
return (react_1.default.createElement(renderer_1.View, { style: styles.productContainer }, products.map((product, index) => (react_1.default.createElement(renderer_1.View, { key: index, style: styles.productSection },
|
|
74
|
+
react_1.default.createElement(renderer_1.Image, { style: styles.image, src: product.Image ||
|
|
75
|
+
'https://cloud-flz4zi76g-hack-club-bot.vercel.app/0image_fallback.jpg' }),
|
|
76
|
+
react_1.default.createElement(renderer_1.View, { style: styles.productTitleBox },
|
|
77
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.productTitle }, product.Title),
|
|
78
|
+
product.Rating && (react_1.default.createElement(renderer_1.Text, { style: styles.productRate },
|
|
79
|
+
"\u2B50 ",
|
|
80
|
+
product.Rating))),
|
|
81
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.productDescription }, product.Description),
|
|
82
|
+
product.Link && typeof product.Link === 'string' && (react_1.default.createElement(renderer_1.Link, { src: product.Link, style: styles.buyButton },
|
|
83
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.productPrice }, `Rs. ${product.Price}`),
|
|
84
|
+
react_1.default.createElement(renderer_1.Text, { style: { marginHorizontal: 5 } }, "Buy Now"))))))));
|
|
85
|
+
};
|
|
86
|
+
exports.default = Template1;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const renderer_1 = require("@react-pdf/renderer");
|
|
8
|
+
const styles = renderer_1.StyleSheet.create({
|
|
9
|
+
productContainer: {
|
|
10
|
+
flexDirection: 'row',
|
|
11
|
+
flexWrap: 'wrap',
|
|
12
|
+
alignItems: 'flex-start',
|
|
13
|
+
justifyContent: 'space-between',
|
|
14
|
+
margin: 10,
|
|
15
|
+
},
|
|
16
|
+
productSection: {
|
|
17
|
+
width: '100%',
|
|
18
|
+
padding: 10,
|
|
19
|
+
marginBottom: 10,
|
|
20
|
+
backgroundColor: '#f2f2f2',
|
|
21
|
+
borderRadius: 5,
|
|
22
|
+
display: 'flex',
|
|
23
|
+
flexDirection: 'row',
|
|
24
|
+
justifyContent: 'space-between',
|
|
25
|
+
},
|
|
26
|
+
productSectionText: {
|
|
27
|
+
width: '50%',
|
|
28
|
+
padding: 10,
|
|
29
|
+
backgroundColor: '#f2f2f2',
|
|
30
|
+
borderRadius: 5,
|
|
31
|
+
display: 'flex',
|
|
32
|
+
flexDirection: 'column',
|
|
33
|
+
justifyContent: 'space-between',
|
|
34
|
+
},
|
|
35
|
+
productSectionImage: {
|
|
36
|
+
width: '50%',
|
|
37
|
+
padding: 10,
|
|
38
|
+
borderRadius: 5,
|
|
39
|
+
display: 'flex',
|
|
40
|
+
flexDirection: 'column',
|
|
41
|
+
justifyContent: 'space-between',
|
|
42
|
+
},
|
|
43
|
+
image: {
|
|
44
|
+
height: 200,
|
|
45
|
+
objectFit: 'contain',
|
|
46
|
+
marginBottom: 10,
|
|
47
|
+
padding: 3,
|
|
48
|
+
},
|
|
49
|
+
productTitle: {
|
|
50
|
+
fontSize: 20,
|
|
51
|
+
fontWeight: 'bold',
|
|
52
|
+
marginBottom: 4,
|
|
53
|
+
},
|
|
54
|
+
productRate: {
|
|
55
|
+
position: 'absolute',
|
|
56
|
+
bottom: 10,
|
|
57
|
+
right: 10,
|
|
58
|
+
},
|
|
59
|
+
productPrice: {
|
|
60
|
+
fontSize: 16,
|
|
61
|
+
color: '#43B446',
|
|
62
|
+
marginTop: 4,
|
|
63
|
+
marginBottom: 4,
|
|
64
|
+
alignSelf: 'flex-end',
|
|
65
|
+
},
|
|
66
|
+
productDescription: {
|
|
67
|
+
fontSize: 10,
|
|
68
|
+
color: '#555555',
|
|
69
|
+
minHeight: 40,
|
|
70
|
+
marginBottom: 10,
|
|
71
|
+
},
|
|
72
|
+
buyButton: {
|
|
73
|
+
fontSize: 12,
|
|
74
|
+
padding: 8,
|
|
75
|
+
backgroundColor: '#ccf9ff',
|
|
76
|
+
color: 'black',
|
|
77
|
+
textAlign: 'center',
|
|
78
|
+
borderRadius: 4,
|
|
79
|
+
borderWidth: 1,
|
|
80
|
+
borderColor: '#000000',
|
|
81
|
+
marginTop: 10,
|
|
82
|
+
textDecoration: 'none',
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
const Template2 = ({ products }) => {
|
|
86
|
+
return (react_1.default.createElement(renderer_1.View, { style: styles.productContainer }, products.map((product, index) => (react_1.default.createElement(renderer_1.View, { key: index, style: styles.productSection },
|
|
87
|
+
react_1.default.createElement(renderer_1.View, { style: styles.productSectionImage },
|
|
88
|
+
react_1.default.createElement(renderer_1.Image, { style: styles.image, src: product.Image ||
|
|
89
|
+
'https://cloud-flz4zi76g-hack-club-bot.vercel.app/0image_fallback.jpg' }),
|
|
90
|
+
product.Rating && (react_1.default.createElement(renderer_1.Text, { style: styles.productRate },
|
|
91
|
+
"\u2B50 ",
|
|
92
|
+
product.Rating))),
|
|
93
|
+
react_1.default.createElement(renderer_1.View, { style: styles.productSectionText },
|
|
94
|
+
react_1.default.createElement(renderer_1.View, { style: {
|
|
95
|
+
display: 'flex',
|
|
96
|
+
flexDirection: 'row',
|
|
97
|
+
justifyContent: 'space-between',
|
|
98
|
+
} },
|
|
99
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.productTitle }, product.Title),
|
|
100
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.productPrice }, `Rs. ${product.Price}`)),
|
|
101
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.productDescription }, product.Description),
|
|
102
|
+
product.Link && typeof product.Link === 'string' && (react_1.default.createElement(renderer_1.Link, { src: product.Link, style: styles.buyButton }, "Buy Now"))))))));
|
|
103
|
+
};
|
|
104
|
+
exports.default = Template2;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const renderer_1 = require("@react-pdf/renderer");
|
|
8
|
+
const styles = renderer_1.StyleSheet.create({
|
|
9
|
+
productSection: {
|
|
10
|
+
width: '100%',
|
|
11
|
+
height: '100vh',
|
|
12
|
+
padding: 20,
|
|
13
|
+
marginBottom: 10,
|
|
14
|
+
backgroundColor: '#f2f2f2',
|
|
15
|
+
borderRadius: 5,
|
|
16
|
+
display: 'flex',
|
|
17
|
+
justifyContent: 'space-between',
|
|
18
|
+
},
|
|
19
|
+
image: {
|
|
20
|
+
width: '100%',
|
|
21
|
+
objectFit: 'contain',
|
|
22
|
+
marginBottom: 10,
|
|
23
|
+
},
|
|
24
|
+
productDetailsBox: {
|
|
25
|
+
backgroundColor: '#FDFD96',
|
|
26
|
+
width: '50%',
|
|
27
|
+
position: 'absolute',
|
|
28
|
+
bottom: 10,
|
|
29
|
+
right: 10,
|
|
30
|
+
textAlign: 'justify',
|
|
31
|
+
padding: 20,
|
|
32
|
+
borderRadius: 8,
|
|
33
|
+
},
|
|
34
|
+
productTitle: {
|
|
35
|
+
fontSize: 20,
|
|
36
|
+
fontWeight: 'bold',
|
|
37
|
+
marginBottom: 4,
|
|
38
|
+
},
|
|
39
|
+
productRate: {},
|
|
40
|
+
productPrice: {
|
|
41
|
+
fontSize: 16,
|
|
42
|
+
color: '#43B446',
|
|
43
|
+
marginTop: 4,
|
|
44
|
+
marginBottom: 4,
|
|
45
|
+
alignSelf: 'flex-end',
|
|
46
|
+
},
|
|
47
|
+
productDescription: {
|
|
48
|
+
fontSize: 10,
|
|
49
|
+
color: '#555555',
|
|
50
|
+
minHeight: 40,
|
|
51
|
+
marginBottom: 10,
|
|
52
|
+
},
|
|
53
|
+
buyButton: {
|
|
54
|
+
fontSize: 12,
|
|
55
|
+
padding: 8,
|
|
56
|
+
backgroundColor: '#ccf9ff',
|
|
57
|
+
color: 'black',
|
|
58
|
+
textAlign: 'center',
|
|
59
|
+
borderRadius: 4,
|
|
60
|
+
borderWidth: 1,
|
|
61
|
+
borderColor: '#000000',
|
|
62
|
+
marginTop: 10,
|
|
63
|
+
textDecoration: 'none',
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
const Template3 = ({ products }) => {
|
|
67
|
+
return (react_1.default.createElement(react_1.default.Fragment, null, products.map((product, index) => (react_1.default.createElement(renderer_1.View, { key: index, style: styles.productSection },
|
|
68
|
+
react_1.default.createElement(renderer_1.Image, { style: styles.image, src: product.Image ||
|
|
69
|
+
'https://cloud-flz4zi76g-hack-club-bot.vercel.app/0image_fallback.jpg' }),
|
|
70
|
+
react_1.default.createElement(renderer_1.View, { style: styles.productDetailsBox },
|
|
71
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.productTitle }, product.Title),
|
|
72
|
+
react_1.default.createElement(renderer_1.View, { style: {
|
|
73
|
+
display: 'flex',
|
|
74
|
+
flexDirection: 'row',
|
|
75
|
+
justifyContent: 'space-between',
|
|
76
|
+
} },
|
|
77
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.productPrice }, `Rs. ${product.Price}`),
|
|
78
|
+
product.Rating && (react_1.default.createElement(renderer_1.Text, { style: styles.productRate },
|
|
79
|
+
"\u2B50 ",
|
|
80
|
+
product.Rating))),
|
|
81
|
+
react_1.default.createElement(renderer_1.Text, { style: styles.productDescription }, product.Description),
|
|
82
|
+
product.Link && typeof product.Link === 'string' && (react_1.default.createElement(renderer_1.Link, { src: product.Link, style: styles.buyButton }, "Buy Now"))),
|
|
83
|
+
react_1.default.createElement(renderer_1.View, { break: true }))))));
|
|
84
|
+
};
|
|
85
|
+
exports.default = Template3;
|