feature/excel #1
@@ -197,6 +197,7 @@ interface ProductData {
|
||||
applicationHtml?: string;
|
||||
images?: string[];
|
||||
featuredImage?: string | null;
|
||||
logoDataUrl?: string | null;
|
||||
categories?: Array<{ name: string }>;
|
||||
attributes?: Array<{ name: string; options: string[] }>;
|
||||
}
|
||||
@@ -204,7 +205,7 @@ interface ProductData {
|
||||
export interface PDFDatasheetProps {
|
||||
product: ProductData;
|
||||
locale: 'en' | 'de';
|
||||
logoUrl?: string;
|
||||
logoDataUrl?: string | null;
|
||||
technicalItems?: KeyValueItem[];
|
||||
voltageTables?: DatasheetVoltageTable[];
|
||||
legendItems?: KeyValueItem[];
|
||||
@@ -485,8 +486,15 @@ export const PDFDatasheet: React.FC<PDFDatasheetProps> = ({
|
||||
<Page size="A4" style={styles.page}>
|
||||
<View style={styles.hero}>
|
||||
<View style={styles.header}>
|
||||
<View>
|
||||
<Text style={styles.logoText}>KLZ</Text>
|
||||
<View style={{ width: 80 }}>
|
||||
{product.logoDataUrl || (product as any).logoDataUrl ? (
|
||||
<Image
|
||||
src={product.logoDataUrl || (product as any).logoDataUrl}
|
||||
style={{ width: '100%', objectFit: 'contain' }}
|
||||
/>
|
||||
) : (
|
||||
<Text style={styles.logoText}>KLZ</Text>
|
||||
)}
|
||||
</View>
|
||||
<Text style={styles.docTitle}>{labels.productDatasheet}</Text>
|
||||
</View>
|
||||
@@ -586,7 +594,16 @@ export const PDFDatasheet: React.FC<PDFDatasheetProps> = ({
|
||||
</View>
|
||||
|
||||
<View style={styles.footer} fixed>
|
||||
<Text style={styles.footerBrand}>KLZ CABLES</Text>
|
||||
<View style={{ width: 60 }}>
|
||||
{product.logoDataUrl || (product as any).logoDataUrl ? (
|
||||
<Image
|
||||
src={product.logoDataUrl || (product as any).logoDataUrl}
|
||||
style={{ width: '100%', objectFit: 'contain' }}
|
||||
/>
|
||||
) : (
|
||||
<Text style={styles.footerBrand}>KLZ CABLES</Text>
|
||||
)}
|
||||
</View>
|
||||
<Text style={styles.footerText}>
|
||||
{new Date().toLocaleDateString(locale === 'en' ? 'en-US' : 'de-DE', {
|
||||
year: 'numeric',
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
public/datasheets/high-voltage/n2xsfl2y-hv-de.pdf
Normal file
BIN
public/datasheets/high-voltage/n2xsfl2y-hv-de.pdf
Normal file
Binary file not shown.
BIN
public/datasheets/high-voltage/n2xsfl2y-hv-en.pdf
Normal file
BIN
public/datasheets/high-voltage/n2xsfl2y-hv-en.pdf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
public/datasheets/high-voltage/na2xsfl2y-hv-de.pdf
Normal file
BIN
public/datasheets/high-voltage/na2xsfl2y-hv-de.pdf
Normal file
Binary file not shown.
BIN
public/datasheets/high-voltage/na2xsfl2y-hv-en.pdf
Normal file
BIN
public/datasheets/high-voltage/na2xsfl2y-hv-en.pdf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -15,6 +15,7 @@ SOURCE_ENV="${1:-}" # local | testing | staging | prod
|
||||
TARGET_ENV="${2:-}" # testing | staging | prod
|
||||
SSH_HOST="root@alpha.mintel.me"
|
||||
LOCAL_MEDIA_DIR="./public/media"
|
||||
LOCAL_DATASHEETS_DIR="./public/datasheets"
|
||||
|
||||
DRY_RUN=""
|
||||
CHECKSUM=""
|
||||
@@ -38,6 +39,16 @@ get_media_path() {
|
||||
esac
|
||||
}
|
||||
|
||||
get_datasheets_path() {
|
||||
case "$1" in
|
||||
local) echo "$LOCAL_DATASHEETS_DIR" ;;
|
||||
testing) echo "/home/deploy/sites/testing.klz-cables.com/public/datasheets" ;;
|
||||
staging) echo "/home/deploy/sites/staging.klz-cables.com/public/datasheets" ;;
|
||||
prod|production) echo "/home/deploy/sites/klz-cables.com/public/datasheets" ;;
|
||||
*) echo "❌ Unknown environment: $1"; exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_app_container() {
|
||||
case "$1" in
|
||||
testing) echo "klz-testing-klz-app-1" ;;
|
||||
@@ -52,35 +63,39 @@ TGT_PATH=$(get_media_path "$TARGET_ENV")
|
||||
TGT_CONTAINER=$(get_app_container "$TARGET_ENV")
|
||||
|
||||
echo "🚀 Syncing assets: $SOURCE_ENV → $TARGET_ENV"
|
||||
echo "📂 Source: $SRC_PATH"
|
||||
echo "📂 Target: $TGT_PATH"
|
||||
|
||||
# ── Execution ──────────────────────────────────────────────────────────────
|
||||
|
||||
if [[ ! -d "$SRC_PATH" ]] && [[ "$SOURCE_ENV" == "local" ]]; then
|
||||
echo "❌ Source directory does not exist: $SRC_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Media Sync ─────────────────────────────────────────────────────────────
|
||||
echo "🖼️ Syncing Media..."
|
||||
if [[ "$SOURCE_ENV" == "local" ]]; then
|
||||
# Local → Remote
|
||||
echo "📡 Running rsync..."
|
||||
rsync -avzi $CHECKSUM --delete --progress $DRY_RUN "$SRC_PATH/" "$SSH_HOST:$TGT_PATH/"
|
||||
elif [[ "$TARGET_ENV" == "local" ]]; then
|
||||
# Remote → Local
|
||||
mkdir -p "$LOCAL_MEDIA_DIR"
|
||||
echo "📡 Running rsync..."
|
||||
rsync -avzi $CHECKSUM --delete --progress $DRY_RUN "$SSH_HOST:$SRC_PATH/" "$TGT_PATH/"
|
||||
else
|
||||
# Remote → Remote (e.g., testing → staging)
|
||||
echo "📡 Running remote rsync..."
|
||||
ssh "$SSH_HOST" "rsync -avzi $CHECKSUM --delete --progress $DRY_RUN $SRC_PATH/ $TGT_PATH/"
|
||||
fi
|
||||
|
||||
# ── Datasheets Sync ────────────────────────────────────────────────────────
|
||||
echo "📄 Syncing Datasheets..."
|
||||
SRC_DS_PATH=$(get_datasheets_path "$SOURCE_ENV")
|
||||
TGT_DS_PATH=$(get_datasheets_path "$TARGET_ENV")
|
||||
|
||||
if [[ "$SOURCE_ENV" == "local" ]]; then
|
||||
ssh "$SSH_HOST" "mkdir -p $TGT_DS_PATH"
|
||||
rsync -avzi $CHECKSUM --delete --progress $DRY_RUN "$SRC_DS_PATH/" "$SSH_HOST:$TGT_DS_PATH/"
|
||||
elif [[ "$TARGET_ENV" == "local" ]]; then
|
||||
mkdir -p "$LOCAL_DATASHEETS_DIR"
|
||||
rsync -avzi $CHECKSUM --delete --progress $DRY_RUN "$SSH_HOST:$SRC_DS_PATH/" "$TGT_DS_PATH/"
|
||||
else
|
||||
ssh "$SSH_HOST" "mkdir -p $TGT_DS_PATH && rsync -avzi $CHECKSUM --delete --progress $DRY_RUN $SRC_DS_PATH/ $TGT_DS_PATH/"
|
||||
fi
|
||||
|
||||
# Fix ownership on remote target if it's not local
|
||||
if [[ "$TARGET_ENV" != "local" && -z "$DRY_RUN" ]]; then
|
||||
echo "🔑 Fixing media file permissions on $TARGET_ENV..."
|
||||
ssh "$SSH_HOST" "docker exec -u 0 $TGT_CONTAINER chown -R 1001:65533 /app/public/media/ 2>/dev/null || true"
|
||||
echo "🔑 Fixing datasheet permissions..."
|
||||
ssh "$SSH_HOST" "chown -R 1001:1001 $TGT_DS_PATH 2>/dev/null || true"
|
||||
fi
|
||||
|
||||
echo "✅ Asset sync complete!"
|
||||
|
||||
@@ -268,7 +268,10 @@ async function processChunk(
|
||||
}
|
||||
|
||||
// Load assets as Data URLs for React-PDF
|
||||
const heroDataUrl = await loadImageAsPngDataUrl(model.product.heroSrc);
|
||||
const [heroDataUrl, logoDataUrl] = await Promise.all([
|
||||
loadImageAsPngDataUrl(model.product.heroSrc),
|
||||
loadImageAsPngDataUrl('/logo-black.svg'),
|
||||
]);
|
||||
|
||||
const fileName = generateFileName(product, locale);
|
||||
const voltageType = (product as any).voltageType || 'other';
|
||||
@@ -281,14 +284,18 @@ async function processChunk(
|
||||
// Render using the unified component
|
||||
const element = (
|
||||
<PDFDatasheet
|
||||
product={{
|
||||
...model.product,
|
||||
featuredImage: heroDataUrl,
|
||||
}}
|
||||
product={
|
||||
{
|
||||
...model.product,
|
||||
featuredImage: heroDataUrl,
|
||||
logoDataUrl,
|
||||
} as any
|
||||
}
|
||||
locale={locale}
|
||||
technicalItems={model.technicalItems}
|
||||
voltageTables={model.voltageTables}
|
||||
legendItems={model.legendItems}
|
||||
logoDataUrl={logoDataUrl}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
@@ -147,7 +147,10 @@ function compactCellForDenseTable(
|
||||
|
||||
function resolveMediaToLocalPath(urlOrPath: string | null | undefined): string | null {
|
||||
if (!urlOrPath) return null;
|
||||
if (urlOrPath.startsWith('/')) return urlOrPath;
|
||||
if (urlOrPath.startsWith('/')) {
|
||||
// Handle Payload API URL prefix: /api/media/file/filename.ext -> /media/filename.ext
|
||||
return urlOrPath.replace(/^\/api\/media\/file\//, '/media/');
|
||||
}
|
||||
if (/^media\//i.test(urlOrPath)) return `/${urlOrPath}`;
|
||||
const mapped = ASSET_MAP[urlOrPath];
|
||||
if (mapped) {
|
||||
|
||||
Reference in New Issue
Block a user